我使用文件描述符来查找可读的套接字并继续阅读。由于某些原因,在线路上没有数据的套接字继续读取并且永远不会返回。有没有办法可以在超时后退出接收?
我正在使用winsock库..
http://tangentsoft.net/wskfaq/newbie.html#timeout
2.15 - 如何更改 Winsock 函数的超时时间?
一些阻塞的 Winsock 函数(例如 connect())嵌入了超时。这背后的理论是只有堆栈拥有设置适当超时所需的所有信息。然而,有些人发现堆栈使用的值对于他们的应用来说太长了;它可以是一分钟或更长时间。
您可以使用 SO_SNDTIMEO 和 SO_RCVTIMEO setsockopt() 选项调整 send() 和 recv() 超时。.
对于其他 Winsock 函数,最好的解决方案是完全避免阻塞套接字。所有非阻塞套接字方法都为您提供了构建自定义超时的方法:
Non-blocking sockets with select() – The fifth parameter to the select() function is a timeout value.
Asynchronous sockets – Use the Windows API SetTimer().
Event objects – WSAWaitForMultipleEvents() has a timeout parameter.
Waitable Timers – Call CreateWaitableTimers() to make a waitable timer, which you can then pass to a function like WSAEventSelect() along with your sockets: if none of the sockets is signalled before the timer goes off, the blocking function will return anyway.
请注意,使用异步和非阻塞套接字,您可以完全避免处理超时。即使 Winsock 很忙,您的程序也会继续工作。因此,您可以让用户自行取消耗时过长的操作,或者只是让 Winsock 的自然超时到期,而不是在您的代码中接管此功能。
您的问题出在尝试填充缓冲区的 while 循环中,只需放置一个 if 语句来检查每个块的最后一个索引是否为 '\0' 然后中断您的 while 循环
do {
len = rcv(s,buf,BUF_LEN,0);
for (int i = 0; i <= len; ++i) {
if (buf[i] >= 32 || buf[i] == '\n' || buf[i] == '\r') { //only write valid chars
result += buf[i]; //final string
}
}
if (buf[len] == '\0') { //buf[len] is the last position in the received chanks
break;
}
} while (inner_result > 0);