阻塞 TCP 套接字超时不工作

timeout for blocking TCP socket not working

请注意:平台是Windows,不是Linux.

我有一个阻塞的 TCP 客户端套接字。连接到远程服务器后,我设置了读取超时时间(远程服务器不稳定,网络不好),然后接收数据。

有时,recv() 函数永远不会 returns,我的程序就死了。

代码如下所示:

// set timeout
{
    int millisec = 1000;
    if(setsockopt(sock_, SOL_SOCKET, SO_RCVTIMEO, (char*)&millisec, sizeof(int))) {
        MessageBox(0, "setsockopt fail", "", 0);
    }
}

unsigned begin_t = time(0);
int r = recv(sock_, ptr, static_cast<int>(size), 0);
unsigned end_t = time(0);

if(end_t - begin_t > 2) {
    MessageBox(0, "over 2 sec", "", 0); // This MessageBox popups some time
}

我在 recv() 函数之前将套接字超时设置为 1 秒。理论上,recv() 永远不会超过 1 秒。但有时,它仍然需要超过 3 秒,然后 MessageBox 出现。

为什么有时超时不起作用?

SO_RCVTIMEO 在阻塞套接字中不受支持。

If a blocking receive call times out, the connection is in an indeterminate state and should be closed. If the socket is created using the WSASocket function, then the dwFlags parameter must have the WSA_FLAG_OVERLAPPED attribute set for the timeout to function properly. Otherwise the timeout never takes effect.

WSASocketWSA_FLAG_OVERLAPPED 结合使用。或 socket()WSA_FLAG_OVERLAPPED 模式的默认值)