C# Socket.BeginReceive/EndReceive
-
In what order is the Socket.BeginReceive/EndReceive functions called? For instance, I call BeginReceive twice, once to get the message length and the second time to get the message itself. Now the scenario is like that, for every message I send, I start waiting for its completion (actually acknowledgment of the message sent, also I wait for the action's completion after receiving the acknowledgment), so I call BeginReceive with each BeginSend, but in each BeginReceive's callback, I check if I'm receiving the length or the message. If I'm receiving the message and have received it completely, then I call another BeginReceive to receive the completion of the action. Now this is where things get out of sync. Because one of my receive callback is receiving bytes which it interprets as the length of them message when in fact it is the message itself. Now how do I resolve it? Here is the code, basically it is too big, sorry for that
public void Send(string message)
{
try
{
bytesSent = 0;writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message); writeDataBuffer = WrapMessage(writeDataBuffer); messageSendSize = writeDataBuffer.Length; clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None, new AsyncCallback(SendComplete), clientSocket); } catch (SocketException socketException) { MessageBox.Show(socketException.Message); } } public void WaitForData() { try { if (! messageLengthReceived) { clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE\_LENGTH\_SIZE - bytesReceived, SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket); } public void Send(string message)
{
try
{
bytesSent = 0;writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message); writeDataBuffer = WrapMessage(writeDataBuffer); messageSendSize = writeDataBuffer.Length; clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, Socket
-
In what order is the Socket.BeginReceive/EndReceive functions called? For instance, I call BeginReceive twice, once to get the message length and the second time to get the message itself. Now the scenario is like that, for every message I send, I start waiting for its completion (actually acknowledgment of the message sent, also I wait for the action's completion after receiving the acknowledgment), so I call BeginReceive with each BeginSend, but in each BeginReceive's callback, I check if I'm receiving the length or the message. If I'm receiving the message and have received it completely, then I call another BeginReceive to receive the completion of the action. Now this is where things get out of sync. Because one of my receive callback is receiving bytes which it interprets as the length of them message when in fact it is the message itself. Now how do I resolve it? Here is the code, basically it is too big, sorry for that
public void Send(string message)
{
try
{
bytesSent = 0;writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message); writeDataBuffer = WrapMessage(writeDataBuffer); messageSendSize = writeDataBuffer.Length; clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None, new AsyncCallback(SendComplete), clientSocket); } catch (SocketException socketException) { MessageBox.Show(socketException.Message); } } public void WaitForData() { try { if (! messageLengthReceived) { clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE\_LENGTH\_SIZE - bytesReceived, SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket); } public void Send(string message)
{
try
{
bytesSent = 0;writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message); writeDataBuffer = WrapMessage(writeDataBuffer); messageSendSize = writeDataBuffer.Length; clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, Socket
Hi, According to the documentation, each BeginXxx needs a corresponding EndXxx, and typically that can be handled by the callback method. I can't tell you what exactly is wrong in your code, however it is my impression your code is too complex and not sufficiently safe. I would code this more defensively, and avoid all the global variables your class seems to hold (receiveDataBuffer, bytesReceived, messageLengthReceived). These are things I would do differently: 1. I would create a little class holding clientSocket, the receive data buffer, an index into it; then create two instances (one for length, one for data) of it for each length+data communication, and pass them as the last parameter to the BeginReceive calls (and retrieve it from the EndReceive calls). 2. I would completely split the WaitForData() method into a WaitForLength method and a WaitForData method. And I would completely split the RecieveComplete() method into a ReceivedLength method and a ReceivedData method. (2) makes messageLengthReceived redundant. (1) avoids the risk of receiveDataBuffer and bytesReceived to contain data belonging to another ongoing communication. I am not saying the problem will be solved by doing this, I do claim the code would be more robust and easier to read, and either the problem is gone, or you'll have a better chance of locating the problem. FWIW: I'm puzzled by AsyncClient.BUFFER_SIZE, it appears only once in the code shown; is it the size required to hold the length part only? Hope this helps.
Luc Pattyn
:badger: :jig: :badger:
Have a look at my entry for the lean-and-mean competition; please provide comments, feedback, discussion, and don’t forget to vote for it! Thank you.
:jig: :badger: :jig:
-
Hi, According to the documentation, each BeginXxx needs a corresponding EndXxx, and typically that can be handled by the callback method. I can't tell you what exactly is wrong in your code, however it is my impression your code is too complex and not sufficiently safe. I would code this more defensively, and avoid all the global variables your class seems to hold (receiveDataBuffer, bytesReceived, messageLengthReceived). These are things I would do differently: 1. I would create a little class holding clientSocket, the receive data buffer, an index into it; then create two instances (one for length, one for data) of it for each length+data communication, and pass them as the last parameter to the BeginReceive calls (and retrieve it from the EndReceive calls). 2. I would completely split the WaitForData() method into a WaitForLength method and a WaitForData method. And I would completely split the RecieveComplete() method into a ReceivedLength method and a ReceivedData method. (2) makes messageLengthReceived redundant. (1) avoids the risk of receiveDataBuffer and bytesReceived to contain data belonging to another ongoing communication. I am not saying the problem will be solved by doing this, I do claim the code would be more robust and easier to read, and either the problem is gone, or you'll have a better chance of locating the problem. FWIW: I'm puzzled by AsyncClient.BUFFER_SIZE, it appears only once in the code shown; is it the size required to hold the length part only? Hope this helps.
Luc Pattyn
:badger: :jig: :badger:
Have a look at my entry for the lean-and-mean competition; please provide comments, feedback, discussion, and don’t forget to vote for it! Thank you.
:jig: :badger: :jig: