异步套接字混淆

本文关键字:套接字 异步 | 更新日期: 2023-09-27 18:30:55

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

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

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

谢谢

异步套接字混淆

在第一个代码中,您有一个争用条件。考虑:

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,这可能会在将数据发送到 HandleDataReceived 方法之前覆盖buffer。我认为您想在转换数据将该接收呼叫移动到:

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