Winsock setting accurately determines the timeout

I try to make my call receive timeout after a certain period of time, and I tried the following sentence here:

Winsock Receive Timeout

in this case, I pass the TIMEVAL structure to select when I call it, the problem is that when I set tv.tv_usec to say about 40 minutes or so, the call timing is immediately turned off and not wait for 40 minutes which I pointed. MSDN states that the timeout for the selection is the maximum time that it will wait, how can I make sure that the selection or acceptance in this case expects a certain period of time before the timeout expires?

#define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <WinSock2.h> #include <Ws2tcpip.h> #include <cstdio> #include <tchar.h> VOID _tmain( int argc, TCHAR *argv[] ) { WSADATA wsaData = { 0 }; ADDRINFOA hINTs = { 0 }; PADDRINFOA pResult = NULL; SOCKET hServerSocket = INVALID_SOCKET, hClientSocket = INVALID_SOCKET; TIMEVAL tv = { 0 }; INT iReturnStatus = -1; DWORD dwRecvTimeout = 30000, // Milliseconds dwSendTimeout = 30000; // Milliseconds fd_set readFDs = { 0 }; if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ) { _tprintf_s( TEXT( "WSAStartup Failed\n" ) ); return; } ZeroMemory( &hINTs, sizeof( hINTs ) ); hINTs.ai_family = AF_INET; hINTs.ai_socktype = SOCK_STREAM; hINTs.ai_protocol = IPPROTO_TCP; hINTs.ai_flags = AI_PASSIVE; if ( getaddrinfo( NULL, TEXT( "9001" ), &hINTs, &pResult ) ) { WSACleanup(); _tprintf_s( TEXT( "getaddrinfo Failed\n" ) ); return; } if ( ( hServerSocket = socket( pResult -> ai_family, pResult -> ai_socktype, pResult -> ai_protocol ) ) == INVALID_SOCKET ) { freeaddrinfo( pResult ); WSACleanup(); _tprintf_s( TEXT( "socket Failed\n" ) ); return; } int iResult = bind( hServerSocket, ( pResult -> ai_addr ), pResult -> ai_addrlen ); if ( iResult == SOCKET_ERROR ) { freeaddrinfo( pResult ); closesocket( hServerSocket ); WSACleanup(); _tprintf_s( TEXT( "bind Failed\n" ) ); return; } freeaddrinfo( pResult ); if ( listen( hServerSocket, SOMAXCONN ) ) { closesocket( hServerSocket ); WSACleanup(); _tprintf_s( TEXT( "listen Failed\n" ) ); return; } hClientSocket = INVALID_SOCKET; for ( ;; ) { tv.tv_usec = 2400000000; // microseconds FD_ZERO( &readFDs ); FD_SET( hServerSocket, &readFDs ); _tprintf( "select()\n" ); iReturnStatus = select( 0, &readFDs, NULL, NULL, &tv ); // Select Error if ( iReturnStatus == SOCKET_ERROR ) { _tprintf( "select Failed\n" ); } // Select Success else if ( iReturnStatus ) { // Connection Established On Server Socket if ( FD_ISSET( hServerSocket, &readFDs ) ) { // Accept Client Connection hClientSocket = accept( hServerSocket, NULL, NULL ); if ( hClientSocket == INVALID_SOCKET ) { _tprintf( "accept Failed\n" ); } else { // Set Recv Timeout setsockopt( hClientSocket, SOL_SOCKET, SO_RCVTIMEO, ( const char * ) &dwRecvTimeout, sizeof( dwRecvTimeout ) ); // Set Send Timeout setsockopt( hClientSocket, SOL_SOCKET, SO_SNDTIMEO, ( const char * ) &dwSendTimeout, sizeof( dwSendTimeout ) ); // Process Client Request(s) // HandleConnection( ClientSocket ); } } // Connection Established On Unknown Socket else { _tprintf( "Invalid Socket Returned\n" ); } } // Select Timeout else { _tprintf( "select Timeout\n" ); } } if ( hServerSocket != INVALID_SOCKET ) closesocket( hServerSocket ); return; } 
+4
source share
2 answers

why is that so?

This is a fix.

Verbatim from MSDN :

tv_sec Time interval, in seconds.

tv_usec Time interval, in microseconds. This value is used in conjunction with the tv_sec member to represent time intervals of values ​​that are not a few seconds .

+4
source

The problem is tv.tv_usec; tv_usec on the man page is of type "long". The value (2400000000) goes beyond the long , and for this reason you get this behavior of the selected system.

If you want you to wait 40 minutes, make sure you use tv.tv_sec.

+2
source

All Articles