简体   繁体   English

来自Winsock的connect()函数超时

[英]Timeout in connect() function from Winsock

Is there any way to decrease the timeout when I call connect() function from Winsock? 当我从Winsock调用connect()函数时,有没有办法减少超时? I think it's almost 30 seconds, I want to put 5 seconds. 我想差不多30秒,我想放5秒钟。

The easiest way is to use the socket in non-blocking mode while connecting, and use select() with a timeout of 5 seconds to check if the socket is writable. 最简单的方法是在连接时以非阻塞模式使用套接字,并使用超时为5秒的select()来检查套接字是否可写。 After select() exits, the connection is either established or not. select()退出后,建立或不建立连接。 If not, consider the connection timed out and perform error handling as needed. 如果不是,请考虑连接超时并根据需要执行错误处理。

You can also call the ConnectEx() function and pass it the OVERLAPPED.hEvent structure with a pre-created event, for which you can wait with WaitForSingleObject() as short as you want. 您还可以调用ConnectEx()函数并将OVERLAPPED.hEvent结构传递给预先创建的事件,您可以根据需要等待WaitForSingleObject()。

ConnectEx() is available only in WindowsXP and above... ConnectEx()仅在WindowsXP及更高版本中可用...

//The HANDLE Socket MUST BE pre-bound with Bind() before calling this function
int ConnectWithTimout(HANDLE Socket, UINT remIP, WORD remPort, UINT milliseconds)
{
    int iRes, Result;
    UINT OptVal, Flags;
    OVERLAPPED Overlapped;
    sockaddr_in socket_info;


    Result= ERROR_UNEXP_NET_ERR;

    ZeroMemory(&socket_info, sizeof(socket_info));
    ZeroMemory(&Overlapped, sizeof(Overlapped));

    socket_info.sin_addr.S_addr = htonl(remIP);
    socket_info.sin_port = htons(remPort);
    socket_info.sin_family = AF_INET;

    Overlapped.hEvent = WSACreateEvent(); 
    if ( ConnectEx(Socket, &socket_info, sizeof(socket_info), NULL, 0, NULL, &Overlapped) )
        printf("WOW! Connection succeeded immediately\n");
    else
    {
        iRes = WSAGetLastError();
        if (iRes == ERROR_IO_PENDING)
        {
            iRes = WaitForSingleObject(Overlapped.hEvent, milliseconds);  //Wait for x milliseconds to connect
            if (iRes == WAIT_OBJECT_0)
            {
                if (!WSAGetOverlappedResult(socket, &Overlapped, &OptVal, FALSE, Flags))
                {
                    iRes = WSAGetLastError();
                    if (iRes == WSAEADDRINUSE)
                        DoError("WSAGetOverlappedResult() reported that the requested local address is already in use or in a TIME_WAIT state")
                    else
                        DoError("WSAGetOverlappedResult() failed with error: ", iRes);
                }
                else
                {
                    OptVal = 1;
                    iRes = setsockopt(Socket, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, PCHAR(&OptVal), sizeof(OptVal));
                    if (iRes == SOCKET_ERROR)
                        DoError("setsockopt(SO_UPDATE_CONNECT_CONTEXT) failed with error: ", WSAGetLastError() );

                    printf("Connected to %s : %s\n", inet_ntoa(socket_info.sin_addr), itoa(ntohs(socket_info.sin_port)));
                    Result=NO_ERROR;
                }
            }
            else
            {
                if (iRes == WAIT_TIMEOUT)
                {
                    DoWarning("ConnectEx() TIMED OUT - ", iRes);
                    Result= ERROR_TIMEOUT;
                }
                else
                    DoError("ConnectEx() failed with error: ", iRes)
            }
        }
        else if (iRes ==  WSAECONNREFUSED)  //After this error, it is OK to try to connect again on this docket.
            DoWarning("ConnectEx() failed with CONNECTION REFUSED: ", 0 )
        else if (iRes =  WSAENETUNREACH)    //After this error, it is OK to try to connect again on this docket.
            DoWarning("ConnectEx() failed with NETWORK UNREACHABLE: ", 0 )
        else if (iRes =  WSAETIMEDOUT)  //After this error, it is OK to try to connect again on this docket.
        {
            DoWarning("ConnectEx() TIMED OUT Immediately:", 0 );
            Result= ERROR_TIMEOUT;
        }
        else
            DoError("ConnectEx() failed with unexpected error: ", iRes )
    }


    WSACloseEvent(Overlapped.hEvent);

    return Result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM