无法在Socket.Receive上立即完成非阻塞套接字操作

时间:2015-07-09 20:56:54

标签: c# sockets tcp tcpclient

我有c#代码发送文件,然后等待ACK。此代码在大多数系统上运行正常,但我们有一个客户端收到错误:A non-blocking socket operation could not be completed immediately.我想知道这是否可能是由防火墙问题引起的,以及是否有任何可以在解决它的代码。下面是用于接收ACK的基本代码,为简洁起见,处理过程。

            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 个答案:

答案 0 :(得分:1)

在MSDN Socket.ReceiveMethod文档中,您可以阅读:

  

如果没有可用于读取的数据,则Receive方法将被阻止   直到数据可用,除非使用设置了超时值   Socket.ReceiveTimeout。如果超出超时值,则接收   call会抛出一个SocketException。如果您处于非阻塞模式,   并且协议栈缓冲区中没有可用的数据,   Receive方法将立即完成并抛出一个   SocketException。您可以使用Available属性来确定是否   数据可供阅读。当Available为非零时,重试   接受手术。