5

我使用文件描述符来查找可读的套接字并继续阅读。由于某些原因,在线路上没有数据的套接字继续读取并且永远不会返回。有没有办法可以在超时后退出接收?

我正在使用winsock库..

4

2 回答 2

9

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 的自然超时到期,而不是在您的代码中接管此功能。

于 2011-07-20T00:19:52.557 回答
0

您的问题出在尝试填充缓冲区的 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);
于 2022-02-26T09:31:06.150 回答