Migwell
Migwell

Reputation: 20107

How do you know if a Socket.Send() has worked?

Quite a simple question - I've been having some TCP packets go missing (they aren't received by the remote socket), so I'm considering resending any packets that don't get received.

However I need to know when send doesn't work in order to do this! I know Send() returns an integer containing the 'The number of bytes sent to the Socket', but even when the other computer receives nothing, this is always the length of the entire buffer, indicating that everything was (theoretically) sent. I also know there's a Socket.Connected property, but that is false even when that data is received, and sometimes true even when it isn't, so that doesn't help either.

So how do I know if Send() has worked?

Upvotes: 1

Views: 2476

Answers (2)

Konkret
Konkret

Reputation: 1021

The ideal way of doing this is to check if the bufferedAmount is zero after you've sent a message. The trick is, you'll have to let your application know you are in fact sending a message.

Upvotes: 0

C.Evenhuis
C.Evenhuis

Reputation: 26446

Send() simply places the data in a buffer for the network adapter to process. When Send() returns, you have no guarantee that a single byte has "left" your computer, even when the socket is in blocking mode.

TCP ensures though that within a connection all data is received in the order it was sent. It never "forgets" a packet in the middle of a conversation, and automatically retransmits data when needed.

To determine whether retransmission is required, the protocol sends acknowledgement messages, but:

  • you can't access them from the Socket class
  • hosts may postpone sending this ACK message

The easiest way to ensure your message has arrived is to let the other party respond to them yourself. If you don't receive a response within a reasonable amount of time, you could treat that connection as broken.

About the whole discussion between Sriram Sakthivel and "the others" - I've had similar problems of receiving duplicate messages and missing others, but in my personal case this was caused by:

  • using BeginReceive() (the async receive method),
  • reusing the same buffer on each BeginReceive() call, and
  • calling BeginReceive() before processing that buffer, causing the buffer to be filled with new data before having read the old message.

Upvotes: 1

Related Questions