Thanks for your response. I remove the ObjectOutputStream and I
changed the way of reading the socket according what you said and it
works !

I can now exchange data between Java and C++. Thank you ! :)

On 6 oct, 23:21, Christopher Head <hea...@gmail.com> wrote:
> On Thu, 6 Oct 2011 01:00:37 -0700 (PDT)
>
> yorick <yorick.bru...@gmail.com> wrote:
> > I have now for the Java (this is unchanged) :
> > ----------------------------------
> > IRobotData data = getRobotData();
> > System.out.println("phi:"+data.getPhi()+",
> > distance:"+data.getDistance());
> > int serDataSize = data.getSerializedSize();
> > System.out.println("serDataSize:"+serDataSize);
> > cos.writeRawVarint32(serDataSize);
> > data.writeTo(cos);
> > cos.flush();
> > oos.flush();
>
> Based on the existence of the line "oos.flush()", you're still using
> ObjectOutputStream. Why? Get rid of it!
>
> Also, you seem to be confused about the nature of TCP. In your Java
> code, you're sending a varint32 followed by an encoded IRobotData. In
> your C++, you're only calling recv() once, then building a
> CodedInputStream over it, trying to parse a varint32, and then calling
> recv() again and expecting to see the IRobotData message at that point.
> TCP is a byte stream. It is NOT a message stream. You will much more
> likely see recv() return the varint32 and the IRobotData in a single
> call. It's possible, though, depending on the network, that it could do
> anything: theoretically, it could return a single byte on each call,
> though that's highly unlikely. You can't just expect to send a block of
> bytes, e.g., a varint32, and expect the same block to come out the
> other side. Notice that your C++ code is reading 4 bytes and then 21
> bytes, while your Java code is (except for the OOS bug) writing a varint
> plus 18 bytes. The first four bytes are probably from the
> ObjectOutputStream, the next 3 might be the varint, or a mixture of the
> ObjectOutputStream header and the varint, and the last 18 are probably
> the encoded data.
>
> Your previous code was OK because you read everything until EOF into an
> std::string, then parsed from there. That works if you're OK waiting
> until the connection is closed to parse things. If you want to parse
> data as it arrives, you need to loop until enough data is received,
> then parse it. It might be easier to use a fixed-size header rather
> than a varint to mark the length of an individual message (a uint32
> would be suitable). Starting from the beginning, you would then loop,
> accumulating data, until you had 4 bytes, then turn those into the
> uint32 indicating how big the rest of the message was. You would then
> loop again, accumulating data, until you had that many bytes. Then you
> could parse the message. If you call recv() with a separate buffer,
> like you're doing here with "buf" and "sizeof(buf)", you may find it
> returns more data than you actually expect, e.g., while you're
> receiving the 4 bytes that make up your uint32, you might actually get,
> say, 20 bytes. You need to keep the remaining 16, because they're part
> of the following message. The alternative is to only receive as much as
> you're willing to deal with in one go, so call recv() with 4 for your
> uint32, then if you receive 3 bytes call recv() again with 1, until you
> have your uint32, then similarly for receiving the full message.
>
> Finally, there's no reason to NUL-terminate your buffers. You construct
> a CodedInputStream and pass it recvSize, so the NUL is meaningless
> (even if you didn't it would be meaningless, as there can be NULs in
> the middle of encoded data).
>
> Chris

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To post to this group, send email to protobuf@googlegroups.com.
To unsubscribe from this group, send email to 
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/protobuf?hl=en.

Reply via email to