开发者

.Net Socket : How to implement AsyncCallback / AsyncWaitHandle better

I am experimenting with building a socket server in C# and one issue I am stuck on is that when I pass an AsyncCallback to my socket's BeginReceive method the callback is being called too soon and I am getting null when I read the IAsyncResult's AsyncState property.

I thought I had 'fixed' this by adding

.AsyncWaitHandle.WaitOne(100);

But the problem is still occurring. Could anyone shed any light on where what I'm doing wrong?

My code is as follows (abbreviated):

   private void Main(){

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


    private void HandleConnection(IAsyncResult status)
    {
        SocketError socketRecieveError;

        _connectionSocket = _listener.EndAccept(status);
        _connectionSocket.BeginReceive(_receivedDataBuffer, 0, _r开发者_C百科eceivedDataBuffer.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);
        }
 ..............
 }


The AsyncState property of IAsyncResult contains the user-defined object that contains information about the asynchronous operation (MSDN). This is the same object that is supplied as parameter "state" when the asynchronous operation is invoked.

In your code, you supply _connectionSocket.Available as user state. I suppose you want to provide your callback method with the number of bytes that were received? This is not the right way to do it.

The would be the correct way to do it:

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);

    ....
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜