2015-04-19 26 views
0

我試圖編寫一個簡單的功能回聲套接字客戶端/服務器。我設法使用客戶端來運行同步服務器,但現在我需要一個異步服務器。Linux重疊I/O TCP套接字服務器沒有正確響應C#異步客戶端

如果我使用微軟的版本,它運行良好,異步服務器

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

微軟異步客戶

https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

什麼我想現在是時候獲得Microsoft異步客戶端通信TE與Linux的C++重疊I/O服務器

http://www.tutorialized.com/tutorial/Linux-C-Overlapped-Server-and-Client-Socket-Example/77220

這裏的問題開始。連接已建立,我可以向服務器發送消息,服務器響應迴應消息(根據調試和終端輸出),但Microsoft ASync客戶端永遠不會在其套接字上獲得響應。

無法將ASync Client連接到重疊I/O服務器嗎?我不知道爲什麼從服務器的答覆永遠不會到達客戶端。調試微軟異步客戶告訴我,Receive功能從未獲得過這一行代碼:

receiveDone.WaitOne(); 

receiveDone是ManualResetEvent的:

private static ManualResetEvent receiveDone = 
      new ManualResetEvent(false); 

語境:

// Receive the response from the remote device. 
Receive(client); 
receiveDone.WaitOne(); 

這裏是回調函數接收,完成後設置receiveDone。 bytesRead不會超過0:

private void ReceiveCallback(IAsyncResult ar) 
{ 
    try 
    { 
     // Retrieve the state object and the client socket 
     // from the asynchronous state object. 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket client = state.workSocket; 

     // Read data from the remote device. 
     int bytesRead = client.EndReceive(ar); 

     if (bytesRead > 0) 
     { 
      // There might be more data, so store the data received so far. 
      state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); 

      // Get the rest of the data. 
      client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
       new AsyncCallback(ReceiveCallback), state); 
     } 
     else 
     { 
      // All the data has arrived; put it in response. 
      if (state.sb.Length > 1) 
      { 
       response = state.sb.ToString(); 
      } 
      // Signal that all bytes have been received. 
      receiveDone.Set(); 
     } 
    } 
    catch (Exception e) 
    { 
     msg("Fail ReceiveCallback: " + e.Message, false); 
    } 
} 

反正這個代碼工作當連接到一個異步服務器,但不重疊的I/O服務器,所以實際上我要求在Overlapped I/O server code要改變什麼,因爲它發送ASync Client可以接收的消息?

這是來自服務器的輸出,如果從異步客戶端發送Hello World

[email protected]:/home/petlar/Host/SockServer# g++ OverlappedServer.cpp -o os.out -lpthread 
[email protected]:/home/petlar/Host/SockServer# ./os.out 
--------------------- 
Received connection from 10.0.2.2 
Read 13 bytes from 4 
Sent 13 bytes to 4 
+0

由於推測線程正在等待事件,因此此代碼不是異步的。這是毫無意義的MSDN示例代碼。你得到可怕的異步代碼,並沒有得到任何好處。 – usr

+0

服務器在完成發送後是否關閉連接? – usr

+0

我不確定微軟的例子是不是很好的異步例子,但是我會盡快改進客戶端,只要能夠建立與服務器的簡單通信即可。沒有服務器等待更多的數據包,並將它們回傳給客戶端。如果我讀取的代碼是正確的,那麼最多可以有100個客戶端,但示例代碼沒有清理和重用套接字等等,因此非常簡單。 – Plarsen

回答

1

客戶端代碼只設置在連接被關閉事件。根據您的評論,服務器不會關閉連接。這就是事件從未設置的原因。

將客戶端代碼丟棄並使用簡單的同步代碼重寫它。 50%的代碼致力於製作異步IO(以破碎的方式)。異步IO不關乎提高網絡效率。它在那裏可以節省線程資源。機會是客戶端不需要的。

+0

永遠不要以爲客戶正在等待關閉連接。我會考慮這個,謝謝! – Plarsen

+0

太棒了,它工作!只要我在迴應消息顯示在客戶端上回顯消息後測試了關閉套接字服務器端。好的,我現在明白客戶端代碼需要刷新了,謝謝! – Plarsen

相關問題