我的套接字客户端似乎没有处理缓冲区已满且需要接收更多数据的情况。
这是我的on receive方法,简单版本:
private void Recieve()
{
this._clientSocket.BeginReceive(this._buffer, 0, this._buffer.Length, 0,
new AsyncCallback(OnReceive), this._clientSocket);
}
private void OnReceive(IAsyncResult result)
{
Socket clientSocket = (Socket)result.AsyncState;
int bytesRead = clientSocket.EndReceive(result);
this.Recieve();
string data = Encoding.ASCII.GetString(this._buffer, 0, bytesRead);
ThreadPool.QueueUserWorkItem(new WaitCallback(this.HandleDataReceived), data);
}
这不处理根本需要接收更多数据的情况。那么我试过这个(http://msdn.microsoft.com/en-us/library/bew39x2a.aspx):
private string receivedString = string.Empty;
private void OnReceive(IAsyncResult result)
{
Socket clientSocket = (Socket)result.AsyncState;
int bytesRead = clientSocket.EndReceive(result);
if (bytesRead > 0)
{
receivedString += Encoding.ASCII.GetString(this._buffer, 0, bytesRead);
this.Recieve();
}
else
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.HandleDataReceived), this.receivedString);
this.receivedString = string.Empty;
}
}
但我遇到的问题是当bytesRead> 0,我再次调用BeginReceive,我没有得到另一个回调。我犯了某种错误吗?
由于
答案 0 :(得分:2)
在第一个代码中,您有竞争条件。考虑:
private void OnReceive(IAsyncResult result)
{
Socket clientSocket = (Socket)result.AsyncState;
int bytesRead = clientSocket.EndReceive(result);
this.Recieve();
string data = Encoding.ASCII.GetString(this._buffer, 0, bytesRead);
ThreadPool.QueueUserWorkItem(new WaitCallback(this.HandleDataReceived), data);
}
您再次致电Receive
,这可能会在您将数据发送到buffer
方法之前覆盖HandleDataReceived
。我想你想在转换数据之后将接收调用移到:
private void OnReceive(IAsyncResult result)
{
Socket clientSocket = (Socket)result.AsyncState;
int bytesRead = clientSocket.EndReceive(result);
string data = Encoding.ASCII.GetString(this._buffer, 0, bytesRead);
ThreadPool.QueueUserWorkItem(new WaitCallback(this.HandleDataReceived), data);
this.Recieve();
}
在第二种情况下,您永远不会读取0个字节,因为套接字正在等待数据。如果没有数据,Socket.Receive将阻止,直到有可用数据,或者直到连接关闭。 BeginReceive
正在等待数据。