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
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.
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.
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
Vous devez vous connecter pour publier un commentaire.
C'est par définition.
Mot à mot de MSDN:
OriginalL'auteur alk
Le problème est avec la télévision.tv_usec; tv_usec comme par page de man est de type 'long'. La valeur (2400000000) est hors de la plage de long et c'est la raison pour laquelle vous faites une telle sélectionnez le comportement du système.
Si vous voulez sélectionner d'attendre 40 min alors assurez-vous d'utiliser la télévision.tv_sec.
Je me demande si tv_usec=2147483647 vraiment conduirait à un temps de 2147s, mais 0.483647 s ... - pas de win32 disponible dès maintenant à vérifier.
OriginalL'auteur Viswesn