2015-07-09 273 views
0

我有發送文件的c#代碼,然後等待ACK。此代碼在大多數系統上都能正常工作,但我們有一個客戶端正在接收錯誤:A non-blocking socket operation could not be completed immediately.我想知道這是否可能是由防火牆問題引起的,並且在代碼中是否有任何可以解決的問題。以下是用於接收ACK的基本代碼,爲簡潔起見,省略了處理。無法在Socket上立即完成無阻塞套接字操作。接收

  using (Socket socket = ConnectSocket(server, port)) 
      { 
       if (socket != null) 
       { 
        socket.Send(bytesSent, bytesSent.Length, 0); 
        socket.ReceiveTimeout = ReceiveTimeout; 
        int bytes; 

        // loop in case the ACK is longer than 256 bytes 
        int failedAttempts = 0; 
        do 
        { 
         bytes = 0; 
         try 
         { 
          bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0); 
         } 
         catch (Exception e) 
         { 
          HandleException(e) // Mostly logging 
         } 
         ack.Append(Encoding.ASCII.GetString(bytesReceived, 0, bytes)); 

         // Break out after 1 minute of no reconnect. 
         if(failedAttempts > 60) 
          bytes = 0; 
        } while (bytes == bytesReceived.Length); 
       } 
      } 

當我打電話給bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0);我錯了嗎?我可以設置Socket.Blocking = true,但看起來這隻會導致代碼凍結。再說一遍,這段代碼適用於除一個客戶端系統之外的所有其他客戶端系統,這讓我想到了防火牆,但他們已經監控了防火牆流量,並且說它沒有被阻止。

謝謝。

+1

這樣的 '錯誤' 是有意設計的。 –

+1

我在你的代碼中看到了很多迷信。您在使用API​​時未理解它們。插座是一個容易被濫用的尖銳工具。你需要更加細緻。 – usr

+0

您只在一個用戶的系統上看到問題,表明這是一個計時問題。你真的很幸運,你的代碼可以在其他系統上工作,因爲這是非阻塞套接字應該如何工作的。 – binki

回答

1

在MSDN文檔Socket.ReceiveMethod,你可以閱讀:

If no data is available for reading, the Receive method will block until data is available, unless a time-out value was set by using Socket.ReceiveTimeout. If the time-out value was exceeded, the Receive call will throw a SocketException. If you are in non-blocking mode, and there is no data available in the in the protocol stack buffer, the Receive method will complete immediately and throw a SocketException. You can use the Available property to determine if data is available for reading. When Available is non-zero, retry the receive operation.