当前位置: 首页 > 面试题库 >

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

戴凯歌
2023-03-14
问题内容

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

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

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

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


问题答案:

您可以使用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。



 类似资料:
  • Hi想知道是否有办法设置套接字的超时,以及在连接握手之前重试的次数。我在非常糟糕的连接模式下测试了我的应用程序,我为我在Volley中的请求设置了重试策略为10秒,但SSL握手似乎是个问题,因为它有一个默认的超时设置为60秒,而Volley超时只被触发当套接字由于尝试次数或超时而失败时。 下面是我的方法: 我正在使用截击来提出我的请求,我实现这一点的方法是: 我还尝试设置了这样的超时:

  • 问题内容: 我想将数据发送到服务器,然后等待一分钟,然后关闭套接字。 怎么做? 问题答案: 你可以试试看 根据您的情况更改套接字的超时!此代码将发送一条消息,然后等待接收消息,直到达到超时!

  • 在套接字最终接受另一端消失的情况下,什么指定了这个超时?是操作系统(Ubuntu 11.04),还是来自TCP/IP规范,还是套接字配置选项?

  • 我知道volley有一个重试策略,但我知道,这是针对套接字超时,而不是连接超时,Apache HttpClient有setConnectionTimeout和setSoTimeout方法,有人知道我是否要为volley framework设置连接超时吗。

  • 测试事件: 函数我的处理程序调用(createStack):

  • 问题内容: 在Java中创建套接字时: 套接字构造函数将在返回之前尝试连接到 host:port 。在Windows上,对于无法访问的主机,此操作几乎立即失败,但是对于Linux,套接字可能最多需要5分钟才能超时。 我知道,如果我可以控制创建套接字,则可以执行以下操作: 但我希望操作系统使用合理的默认值。有没有办法在Linux上更改此设置? 谢谢 问题答案: 我想你要。默认值通常是5或6,大约需要