【问题标题】:Why SO_RCVTIMEO timeout differs after it was set?为什么 SO_RCVTIMEO 超时设置后会有所不同?
【发布时间】:2017-03-01 16:25:14
【问题描述】:

我在 Fedora 25 上。在以下测试程序中,我使用 setsockopt 将 recv 超时设置为 12 秒、12345 微秒。但是当我使用getsockopt 获得超时值时,我得到的值略有不同:12 秒,13000 微秒。我希望它与setsockopt 设置的相同。

为什么不一样?

[ ~]$ cat sockopt.c
#include <stdio.h>
#include <sys/time.h>
#include <sys/socket.h>

int main()
{
    int sd = socket(AF_INET, SOCK_STREAM, 0);
    int rc;
    struct timeval tv;
    socklen_t len = sizeof(tv);

    tv.tv_sec = 12;
    tv.tv_usec = 12345;
    rc = setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    if (rc < 0) printf("oops\n");

    rc = getsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, &tv, &len);
    if (rc < 0) printf("oops\n");
    printf("%ld, %ld\n",  tv.tv_sec, tv.tv_usec);
}
[ ~]$ 
[ ~]$ gcc -Wall sockopt.c
[ ~]$ 
[ ~]$ ./a.out 
12, 13000
[ ~]$ 

【问题讨论】:

  • 可能系统没有您要求的分辨率,可能会向上取整到最接近的微秒?
  • @Someprogrammerdude:实际上是四舍五入到最接近的毫秒,问题提到的毫秒不正确,tv_usec 以微秒为单位。
  • @BenVoigt,谢谢,编辑了问题。

标签: c linux sockets tcp


【解决方案1】:

根据内核sources:在设置SO_RCVTIMEO 时,将struct tv 转换为long 值,对HZ 值使用算术运算。另一方面,当检索SO_RCVTIMEO 值时,struct tv 是从long 值构造的。因此,结果取决于时间分辨率(HZ 值)以及算术除法和模数。

【讨论】:

    猜你喜欢
    • 2014-05-19
    • 2019-01-10
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多