2012-06-12 4 views
4

여기에 제안 다음 내가 일정 기간 후 내 동의를 호출 제한 시간을 만들려고 노력하고 내가 시도 : 나는 timeval 형 구조체를 통과하는 경우설정 Winsock을 선택 제한 시간을 정확하게

Winsock accept timeout

선택 나는 그것을 부른다. 문제는 내가 tv.tv_usec을 약 40 분 정도 말하도록 설정했을 때, 내가 지정한 40 분을 기다리는 대신에 선택 호출이 즉시 타임 아웃된다. MSDN은 select에 대한 타임 아웃이 기다리는 최대 시간임을 알려주며, 타임 아웃 전에 특정 시간 동안 기다리거나 선택하도록하는 방법은 무엇입니까?

#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; 
} 
+1

MSDN은 소켓이 수락시 차단되지 않으면 '선택'대기가 끝나기 때문에 최대 시간을 말합니다. 따라서 선택 호출이 올바르지 않거나 청취 소켓에서 연결을 사용할 수 없습니다. 일부 코드를 게시하면 도움이 될 수 있습니다. – Gene

+0

Checkout은 제한 시간을 초 또는 분 단위로 지정합니다. 나는 그것이 몇 분 안에 초 안에 있어야한다고 생각한다. – Viswesn

+0

'tv.tv_usec'는 마이크로 초이고,'tv.tv_sec'는 초입니다. 또한, struct/fd_sets와'select' 호출을 초기화하는데 사용하는 코드를 보여주십시오. –

답변

4

왜 그럴까요?

이것은 정의에 따른 내용입니다. MSDN에서

축어 :

초에 시간 간격 tv_sec가.

tv_usec 시간 간격 (마이크로 초). 이 값은 시간 간격 값을 표시하기 위해 초 단위로 초 단위로과 함께 사용됩니다.

2

문제는 tv.tv_usec; man 페이지 당 tv_usec 유형은 'long'입니다. 값 (2400000000) 이 긴 범위를 벗어났습니다. 그런 이유로 이러한 시스템 동작이 선택됩니다.

40 분 동안 기다리려면 tv.tv_sec를 사용하고 있는지 확인하십시오.

+0

long의 범위는 -2147483648과 2147483647입니다. – Viswesn

+0

tv_usec = 2147483647이 실제로 2147s의 시간을 가져 오지 만, 0.483647s가 될지 궁금합니다. - 사용 가능한 win32가 없습니다. 지금 확인해 봐. – alk

관련 문제