异步客户端句柄接收?

时间:2011-10-30 17:16:53

标签: c# .net-4.0 asyncsocket

有几次我被告知异步更好或我应该使用异步而不是同步套接字,因此开始学习它,但我已经很难了。

我已经基本了解了回调的工作原理以及如何建立连接。

I am using this msdn code as reference!

我对代码遇到的一些问题:

  • 目前该代码将连接到服务器,发送文本,读取响应并退出。我怎么这样做我可以继续接收数据,直到服务器断开我和/或我自己结束它?我不太清楚我应该怎么做,如果我需要将它包装在一个带有while或简单调用的线程上,一旦ReceiveCallback完成就再次接收。

  • 我注意到的另一件事是,当它连接时,套接字被分配给客户端,但代码本身总是重新分配客户端套接字,与同步套接字相比,我不太了解我们一直在咨询的插座等。

我不确定我使用的参考文件的年龄有多大,但如果您能帮助我提供一些我已经指出的示例,我会很感激,因为我更容易理解。

更新:

    private void SetupRecieveCallback(Socket sock)
    {
        new Thread(
            delegate()
            {
                while (isReceiving)
                {
                    _receiveQueue.Reset();
                    try
                    {
                        AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
                        sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error("Setup Recieve Callback failed! " + ex.Message);
                    }
                    _receiveQueue.WaitOne();
                }
            }
        ).Start();
        /*
                    // The original code
        try
        {
            AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
            sock.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock);
        }
        catch (Exception ex)
        {
            _logger.Error("Setup Recieve Callback failed! " + ex.Message);
        }
        */
    }

1 个答案:

答案 0 :(得分:1)

只需在回调中再次调用BeginReceive()即可继续接收。当服务器断开连接时,将调用您的回调,EndReceive()将抛出ObjectDisposedException。这就是你知道如何停止调用BeginReceive()。

第二个问题难以解码(只问一个)。我猜你对这句话感到困惑:

private static void ConnectCallback(IAsyncResult ar) {
    try {
        // Retrieve the socket from the state object.
        Socket client = (Socket) ar.AsyncState;
        // etc..

此处没有重新分配套接字。代码只是检索对原始套接字的引用。这是一种有用的技术,它允许多个连接使用此回调。 ar.AsyncState值必须是此语句的套接字:

        client.BeginConnect( remoteEP, 
            new AsyncCallback(ConnectCallback), client);

请注意 client 是如何传递给AsyncCallback构造函数的。在回调中检索的完全相同的客户端。任何对象都可以传递。