.Net Socket:如何更好地实现AsyncCallback / AsyncWaitHandle

时间:2011-01-27 10:59:09

标签: c# .net sockets asyncsocket

我正在尝试用C#构建套接字服务器,我遇到的一个问题是,当我将 AsyncCallback 传递给我的套接字的 BeginReceive 方法时,回调就是调用太快,当我读到IAsyncResult的 AsyncState 属性时,我变为null。

我以为我通过添加

来“修复”了这个问题
.AsyncWaitHandle.WaitOne(100);

但问题仍然存在。谁能说清楚我做错了什么?

我的代码如下(缩写):

   private void Main(){

        _listener.BeginAccept(new AsyncCallback(HandleConnection), null);
    }


    private void HandleConnection(IAsyncResult status)
    {
        SocketError socketRecieveError;

        _connectionSocket = _listener.EndAccept(status);
        _connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError,
                                      new AsyncCallback(HandleHandshake), _connectionSocket.Available);

        if(socketRecieveError !=  SocketError.Success)
            _logger.Log("Socket error: " + socketRecieveError);
    }


    private void HandleHandshake(IAsyncResult status)
    {

        status.AsyncWaitHandle.WaitOne(1000);

        int handshakeLength;

        try
        {
            handshakeLength = Convert.ToInt32(status.AsyncState); // <--- BOOOM
        }
        catch (Exception ex)
        {
            _logger.Log(ex.Message);
        }
 ..............
 }

1 个答案:

答案 0 :(得分:1)

IAsyncResult的AsyncState属性包含用户定义的对象,该对象包含有关异步操作(MSDN)的信息。这是在调用异步操作时作为参数“state”提供的同一对象。

在您的代码中,您将_connectionSocket.Available作为用户状态提供。我想你想为你的回调方法提供收到的字节数?这不是正确的方法。

这是正确的方法:

private void HandleConnection(IAsyncResult status)
{
    SocketError socketRecieveError;

    _connectionSocket = _listener.EndAccept(status);
    _connectionSocket.BeginReceive(_receivedDataBuffer, 0, _receivedDataBuffer.Length, 0, out socketRecieveError, new AsyncCallback(HandleHandshake), null);

    if(socketRecieveError !=  SocketError.Success)
        _logger.Log("Socket error: " + socketRecieveError);
}

private void HandleHandshake(IAsyncResult ar)
{
    int bytesReceived = _connectionSocket.EndReceive(ar);

    ....
}