【发布时间】:2019-05-15 08:06:04
【问题描述】:
请注意:平台是 Windows,而不是 Linux。
我有一个阻塞的 TCP 客户端套接字。连接远程服务器后,我设置了读取超时(远程服务器不稳定,网络条件不好),然后接收数据。
有时,recv() 函数永远不会返回,我的程序已经死了。
代码如下:
// 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。
为什么有时超时不起作用?
【问题讨论】:
-
time()具有秒精度,因此对于时序代码来说不会很准确。请改用GetTickCount/64()或QueryPerformanceCounter() -
也许我不需要计算时间成本,因为有时它永远不会回来。
-
当非无限
SO_RCVTIMEO超时生效时,recv()根本不可能永远阻塞。所以其他事情正在发生。另外,仅供参考,实现读取超时的另一种方法是在调用recv()之前调用select()。 -
套接字是否具有
OVERLAPPED属性?
标签: sockets winapi socket-timeout-exception winsockets