Socket ReceiveTimeout

2019-06-17 18:42发布

问题:

I have specified the ReceiveTimout as 40 ms. But it takes more than 500ms for the receive to timeout. I am using a Stopwatch to compute the timetaken.

The code is shown below.

Socket TCPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
                              ProtocolType.Tcp);
TCPSocket.ReceiveTimeout = 40;

try
{  
    TCPSocket.Receive(Buffer);  

}  catch(SocketException e)  {  }

回答1:

You can synchronously poll on the socket with any timeout you wish. If Poll() returns true, you can be certain that you can make a call to Receive() that won't block.

Socket s;
// ...
// Poll the socket for reception with a 10 ms timeout.
if (s.Poll(10000, SelectMode.SelectRead))
{
    s.Receive(); // This call will not block
}
else
{
    // Timed out
}

I recommend you read Stevens' UNIX Network Programming chapters 6 and 16 for more in-depth information on non-blocking socket usage. Even though the book has UNIX in its name, the overall sockets architecture is essentially the same in UNIX and Windows (and .net)



回答2:

You cannot use timeout values which are less than 500ms. See here for SendTimeout: http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.sendtimeout

Even though MSDN doesn't state the same requirement for the ReceiveTimeout, my experience shows that this restriction is still there.

You can also read more about this on several SO posts:

  • Setting socket send/receive timeout to less than 500ms in .NET
  • WinSock recv() timeout: setsockopt()-set value + half a second?


回答3:

I found this one:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

IAsyncResult result = socket.BeginConnect( sIP, iPort, null, null ); 

bool success = result.AsyncWaitHandle.WaitOne( 40, true ); 

if ( !success ) 
{           

            socket.Close(); 
            throw new ApplicationException("Failed to connect server."); 
}