3
votes

My application needs to send/receive xml data via a tcp socket. There is no way to include any kind of a fixed-length header containing message length. As far as I understand, data transmitted over tcp can come to the receipient like this.

  1. <messa

  2. ge><content

  3. >hi</content>

  4. </message>

But somehow this never happens meaning that data sent with one Send() operation (assuming it's shorter or equal than socket buffer size) is always read completely with one Receive() operation. Is the above scenario possible given that socket buffers of the endpoints are large enough and never exceeded?

3

3 Answers

4
votes

Yes, it is possible.

You really can not assume that the buffer boundaries in the send() operation on one side will match with the ones seen by the corresponding recv() at the other end, even if that appears to be the case most of the time.

For example, if you're sending a lot of data, it's possible that the receiving OS will invoke TCP flow control and the sending OS will only be able to send part of a buffer. Or maybe the underlying network has a packet size limitation that requires things to be split up, or ...

1
votes

This can easily happen if there is a proxy between. If we assume there is no proxy, the client will receive the same packets as the server sends. If you send data in pieces less than TCP MSS of your link, the client will probably receive it in one piece.

However, I would not rely on this. It is easy to tell the end of an XML message by seeing the close tag (</message>), so it's easy to parse XML from a stream.

0
votes

You can include the message length in your messages. All you have to do is, when you send the xml msg you prepend it with the msg length in the first 4 bytes and then the xml msg. When you receive you take the first 4 bytes of the stream as the msg length and then read each byte for the xml msg