2015-07-09 269 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.