0

我的套接字客户端似乎没有处理缓冲区已满并且要接收更多数据的情况。

这是我的接收方法,简单版本:

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 时,我没有得到另一个回调。我犯了某种错误吗?

谢谢

4

1 回答 1

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覆盖。我认为您希望在转换数据将该 Receive 呼叫移至:bufferHandleDataReceived

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正在等待数据。

于 2013-09-10T14:33:45.117 回答