2011-10-30 70 views
0

我被多次告知,異步更好,或者我應該使用異步而不是同步套接字,因此開始學習它,但已經有困難了。異步客戶端句柄接收?

我已經對回調的工作原理以及如何建立連接有了基本的瞭解。

I am using this msdn code as reference!

我的代碼有幾個問題:

  • 目前該代碼將連接到服務器,發送文本,讀取響應並退出。我該怎麼做才能繼續接收數據,直到服務器斷開連接並且/或者我自己終止數據?我不太清楚我該怎麼做,如果我需要將它封裝在線程上,或者簡單調用ReceiveCallback完成後再次接收。

  • 我注意到的另一件事是,當它連接時,套接字被分配給客戶端,但代碼本身總是重新分配客戶端套接字,我不明白與同步套接字相比,我們有一個主套接字我們總是諮詢等

我不知道在我使用的參考幾歲了,但會很感激,如果你能幫助我與我所指出的例子,因爲它是對我來說更容易瞭解。

UPDATE:

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

只需在回調再次調用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); 

客戶是如何傳遞給AsyncCallback的構造。在回調中檢索到的完全相同的客戶端。任何對象都可以傳遞。

+0

我明白了,關於BeginReceive我不得不在'SetupRecieveCallback(Socket sock)'上使用manualevent和循環來保持它的活躍狀態,而不是退出應用程序,因爲一旦沒有數據接收它就離開不停地等待更多的是正常的方法?將用我在底部做的事例來更新這個問題。 – Guapo

+0

如果您在Main()方法中沒有任何操作,那麼您的應用程序將在退出時終止。不知道你想在那裏做什麼,Console.ReadLine()會阻止它。 –

+0

漢斯非常感謝,似乎這個問題確實做了一個簡單的時間(停下來)只是爲了檢查它和插座保持良好。事實上,使用同步套接字似乎好得多,只是收到幾個數據包,我已經注意到一些差異,這將會爲我節省大量代碼。 – Guapo