1

I'm implementing a client-server app using C# Socket class (with async methods and SocketAsyncEventArgs Class). i must implement both TCP and UDP functionality.

My usage is sending some Commands in form of Packets from server to client and vise versa using TCP for important commands and UDP for non-important commands.

it's said that Nagle algorithm may cause merging multiple Sends to one Receive for TCP packets so i set NoDelay for TCP Sockets (though i had never experienced it!)

another problem may be IP fragmentation but i think assembling fragments occurs somewhere before Receive. so it must be safe to send up to 64KB to Send and Receive at once!

My Question:: Can I Assume that every one Receive corresponds to one Send in 100% cases? (I know that One send may cause zero Receive for UDP lost Packets)

My Reason for asking: should I implement 1)Splitting Merged Packets or 2)Merging split Packets in Receive or is there some circumstances that I can safely assume that 100% every One Receive Corresponds to One Send?

P.S: I'm Using Socket.ReceiveAsync for TCP and Socket.ReceiveFromAsync for UDP packets.

Mokhabadi
  • 302
  • 2
  • 14

1 Answers1

3

No, for TCP you cannot rely on this at all. One Send may require multiple Receive calls to read, and multiple Sends may be received by a single call to Receive, there is nothing you can do (in terms of settings on the connection) to prevent this, so you must be able to handle it within your application.

If you are exchanging variable length messages over a TCP stream, the usual way to determine whether the entire message has been read is to implement some form of "framing" whereby you prefix each message with a fixed number of bytes (e.g. 4 bytes to encode an Int32) that specify the size of the following message.

On your receiving side, you first read the first 4 byte prefix (remembering that you may need to do this with multiple Receives!), convert it to an Int32 which then tells you how many more bytes you'll need to read to ensure you have read exactly one message from the stream. To read the next message simply repeat the process.

Iridium
  • 23,323
  • 6
  • 52
  • 74
  • Thanks! Can you please Specify where and why this may occur? what you suggest is exactly what i had intent to implement but in my experiences it seemed to be redundant because i didn't experienced merge/split. – Mokhabadi Aug 21 '20 at 09:40
  • Do you mean that in some points in the way some router or ISP may merge or split packets? for both TCP and UDP? – Mokhabadi Aug 21 '20 at 09:44
  • 1
    @Mokhabadi - It could occur at any point along the data path and for a number of reasons - as an example (but not the only reason it can occur), the data you `Send()` is split into packets (of a limited size) to be sent out over the wire. If you're on a slow link and call `Receive()` at your destination before all the packets have arrived, your OS may give you all the data it's received so far, but that would be less than the amount passed to `Send()` at the source. On the other hand, UDP is a datagram protocol, so is intended for sending messages, rather than a stream of data like TCP – Iridium Aug 21 '20 at 18:11