P
Pete Davis
I'm trying to do async socket IO in a socket server in C# and I'm having
trouble on the receive side of things.
I've tried variations of the code below and I just can't seem to get it to
work. I think my _receiveEvent.Set() calls may be misplaced among other
things. EndReceive() gets called when the first message is sent.
What I want it to do is to continue to receive until the entire message has
arrived. I'm not really sure how to accomplish that. Once a full message has
arrived, I want to process the message (which generally involves a reply)
and then continue receiving.
Thanks for any help anyone can provide.
Pete Davis
private void CommunicationThread()
{
Monitor.Enter(_socketStates);
SocketState sockState = (SocketState) _socketStates[Thread.CurrentThread];
sockState.Connected = true;
Monitor.Exit(_socketStates);
try
{
_receiveEvent.Reset();
sockState.RemoteSocket.BeginReceive(sockState.ReceiveBuffer, 0,
SocketState.BufferSize, 0, new AsyncCallback(this.ReadCallback), sockState);
_receiveEvent.WaitOne();
}
catch(SocketException se)
{
sockState.Connected = false;
LogException(se);
}
catch(System.Exception ex)
{
sockState.Connected = false;
LogException(ex);
}
return;
}
private void ReadCallback(IAsyncResult asyncResult)
{
SocketState socketState = (SocketState) asyncResult.AsyncState;
int bytesRead = 0;
try
{
bytesRead = socketState.RemoteSocket.EndReceive(asyncResult);
Debug.WriteLine("SocketServer.ReadCallback: EndReceive completed");
}
catch (SocketException se)
{
// Likely the socket timed out.
LogException(se);
_receiveEvent.Set();
return;
}
Debug.WriteLine(String.Format("SocketServer.ReadCallback: End receive with
{0} bytes", bytesRead));
// Append new data until all data received
if (bytesRead > 0)
{
socketState.DataReceived = bytesRead;
socketState.BufferUpdate();
sockState.RemoteSocket.BeginReceive(socketState.ReceiveBuffer, 0,
SocketState.BufferSize, 0, new AsyncCallback(this.ReadCallback),
socketState);
_receiveEvent.Set();
return;
}
// All data received. Handle message
else
{
HandleMessage(socketState);
}
_receiveEvent.Set();
}
trouble on the receive side of things.
I've tried variations of the code below and I just can't seem to get it to
work. I think my _receiveEvent.Set() calls may be misplaced among other
things. EndReceive() gets called when the first message is sent.
What I want it to do is to continue to receive until the entire message has
arrived. I'm not really sure how to accomplish that. Once a full message has
arrived, I want to process the message (which generally involves a reply)
and then continue receiving.
Thanks for any help anyone can provide.
Pete Davis
private void CommunicationThread()
{
Monitor.Enter(_socketStates);
SocketState sockState = (SocketState) _socketStates[Thread.CurrentThread];
sockState.Connected = true;
Monitor.Exit(_socketStates);
try
{
_receiveEvent.Reset();
sockState.RemoteSocket.BeginReceive(sockState.ReceiveBuffer, 0,
SocketState.BufferSize, 0, new AsyncCallback(this.ReadCallback), sockState);
_receiveEvent.WaitOne();
}
catch(SocketException se)
{
sockState.Connected = false;
LogException(se);
}
catch(System.Exception ex)
{
sockState.Connected = false;
LogException(ex);
}
return;
}
private void ReadCallback(IAsyncResult asyncResult)
{
SocketState socketState = (SocketState) asyncResult.AsyncState;
int bytesRead = 0;
try
{
bytesRead = socketState.RemoteSocket.EndReceive(asyncResult);
Debug.WriteLine("SocketServer.ReadCallback: EndReceive completed");
}
catch (SocketException se)
{
// Likely the socket timed out.
LogException(se);
_receiveEvent.Set();
return;
}
Debug.WriteLine(String.Format("SocketServer.ReadCallback: End receive with
{0} bytes", bytesRead));
// Append new data until all data received
if (bytesRead > 0)
{
socketState.DataReceived = bytesRead;
socketState.BufferUpdate();
sockState.RemoteSocket.BeginReceive(socketState.ReceiveBuffer, 0,
SocketState.BufferSize, 0, new AsyncCallback(this.ReadCallback),
socketState);
_receiveEvent.Set();
return;
}
// All data received. Handle message
else
{
HandleMessage(socketState);
}
_receiveEvent.Set();
}