一尘不染

建立多个连接时如何在C中设置套接字超时?

linux

我正在编写一个简单的程序,该程序将多个连接连接到不同的服务器以进行状态检查。所有这些连接都是按需构建的;最多可以同时创建10个连接。我不喜欢“每个套接字一个线程”的想法,因此我将所有这些客户端套接字都设置为“非阻塞”,然后将其放入select()池中。

效果很好,直到我的客户抱怨目标服务器停止响应时,等待时间太长才能获得错误报告。

我已经在论坛中检查了几个主题。有人建议可以使用alarm()信号或在select()函数调用中设置超时。但是我正在处理多个连接,而不是一个。当发生进程范围的超时信号时,我无法在所有其他连接中区分超时连接。

无论如何,有没有改变系统默认的超时时间?


阅读 229

收藏
2020-06-02

共1个答案

一尘不染

您可以使用SO_RCVTIMEO和SO_SNDTIMEO套接字选项来设置任何套接字操作的超时,如下所示:

    struct timeval timeout;      
    timeout.tv_sec = 10;
    timeout.tv_usec = 0;

    if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
                sizeof(timeout)) < 0)
        error("setsockopt failed\n");

    if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,
                sizeof(timeout)) < 0)
        error("setsockopt failed\n");

编辑:setsockopt
手册页

SO_SNDTIMEO是为输出操作设置超时值的选项。它接受结构timeval参数,该参数具有用于限制等待输出操作完成的秒数和微秒数。如果发送操作阻塞了这么长时间,则如果没有发送数据,它将以部分计数或错误EWOULDBLOCK返回。在当前实现中,每次将其他数​​据传递到协议时,都会重新启动此计时器,这意味着该限制适用于大小从低水位标记到高水位标记的输出部分,以进行输出。

SO_RCVTIMEO是为输入操作设置超时值的选项。它接受结构timeval参数,该参数的秒数和微秒数用于限制输入操作完成的等待时间。在当前的实现中,每次协议接收到其他数据时,都会重新启动此计时器,因此该限制实际上是不活动计时器。如果接收操作被阻塞了这么长时间而没有接收到其他数据,则如果没有接收到数据,则返回计数很短,或者返回错误EWOULDBLOCK。struct
timeval参数必须表示一个正的时间间隔。否则,setsockopt()返回错误EDOM。

2020-06-02