Réglage de winsock sélectionnez timeout avec précision

Je suis en train de faire mes accepter l'appel timeout au bout d'une certaine période de temps et j'ai essayé de suivre la suggestion ici:

Winsock accepter délai d'attente

dans ce cas, je passe une struct TIMEVAL pour sélectionner quand je l'appelle il, problème est lorsque j'ai mis la tv.tv_usec-à-dire environ 40 minutes ou plus, l'sélectionnez appel immédiatement au lieu d'attendre les 40 minutes que j'ai précisé. MSDN indique que le délai d'attente pour sélectionner est le temps maximum qu'il va attendre, comment dois-je faire en sorte de choisir ou accepter pour cette question attend pour une période de temps spécifique, avant d'expirer?

#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;
}
MSDN dit max de temps parce que la select attente se termine si le support ne va pas bloquer sur accepter. Donc, soit vous sélectionnez appel n'est pas correcte ou qu'une connexion est disponible sur le socket d'écoute. Si tu postes du code, il pourrait être possible de vous aider.
La caisse, est le délai d'attente spécifie, en secondes ou en minutes. Je pense que cela doit être dans les secondes n'en minutes.
tv.tv_usec est microsecondes, et tv.tv_sec est secondes. Aussi, s'il vous plaît montrer le code que vous utilisez pour l'initialisation de la structure/fd_sets et la select appel.
Parce que vous utilisez tv_sec délais d'attente PLUS de 1 seconde, tv_usec délais d'attente MOINS de 1 seconde, et vous devez vous PAS permet de tv_usec > de 1 000 000.
tv.tv_sec = ( timeout_in_microseconds / 1000000 ); tv.tv_usec = ( timeout_in_microseconds % 1000000 );

OriginalL'auteur shawn | 2012-06-12