WinSock recv() timeout: setsockopt()-set value + half a second?
I am writing a cross-platform library which, among other things, provides a socket interface, and while running my unit-test suite, I noticed something strange with regard to timeouts set via setsockopt()
: On Windows, a blocking recv()
call seems to consistently return about half a second (500 ms) later than specified via the SO_RCVTIMEO
option.
Is there any explanation for this in the docs I missed? Searching the web, I was only able to find a single other reference to the problem – could somebody who owns »Windows Sockets Network Programming« by Bob Quinn and Dave Shute look up page 466 for me? Un开发者_如何学JAVAfortunately, I can only run my test Windows Server 2008 R2 right now, does the same strange behavior exist on other Windows versions as well?
From Networking Programming for Microsoft Windows by Jones and Ohlund:
SO_RCVTIMEO optval
- Type: int
- Get/Set: Both
- Winsock Version: 1+
- Description : Gets or sets the timeout value (in milliseconds) associated with receiving data on the socket
The SO_RCVTIMEO option sets the receive timeout value on a blocking socket. The timeout value is an integer in milliseconds that indicates how long a Winsock receive function should block when attempting to receive data. If you need to use the SO_RCVTIMEO option and you use the WSASocket function to create the socket, you must specify WSA_FLAG_OVERLAPPED as part of WSASocket's dwFlags parameter. Subsequent calls to any Winsock receive function (such as recv, recvfrom, WSARecv, or WSARecvFrom) block only for the amount of time specified. If no data arrives within that time, the call fails with the error 10060 (WSAETIMEDOUT). If the receiver operation does time out the socket is in an indeterminate state and should not be used.
For performance reasons, this option was disabled in Windows CE 2.1. If you attempt to set this option, it is silently ignored and no failure returns. Previous versions of Windows CE do implement this option.
I'd think the crucial information in this is:
If you need to use the SO_RCVTIMEO option and you use the WSASocket function to create the socket, you must specify WSA_FLAG_OVERLAPPED as part of WSASocket's dwFlags parameter
I hope this is still useful :)
I am having the same problem. Going to use
patchedTimeout = max ( unpatchedTimepit - 500, 1 )
Tested this with the unpatchedTimepit == 850
your problem is not in rcv function timeout!
if your application have a while loop to check and receive just put an if statement to check the receive buffer last index for '\0' char to check is the receiving string is ended or not.
typically if rcv function is still receiving return value is the size of received data. size can be used as last index of buffer array.
do{
result = rcv(s,buf,len,0);
if(buf[result] == '\0'){
break;
}
}
while(result > 0);
精彩评论