2017-03-01 130 views
1

我在Fedora 25上。在以下测试程序中,我将recv超时设置为12秒,12345微秒与setsockopt。但是当我用getsockopt获得超时值时,我会得到稍微不同的值:12秒,13000微秒。我预计它会和setsockopt设置的一样。为什么SO_RCVTIMEO在设置后超时有所不同?

为什么不同?

[ ~]$ 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 
[ ~]$ 
+0

也许系统没有您要求的分辨率,并且可能达到最接近的微秒? –

+0

@Someprogrammerdude:它实际上是四舍五入到最接近的毫秒,问题提到的毫秒是不正确的,'tv_usec'以微秒为单位。 –

+0

@BenVoigt,谢谢,编辑了这个问题。 – ks1322

回答

0

根据内核sources:设置SO_RCVTIMEOstruct tv转换成long值,使用上HZ值算术。另一方面,当检索SO_RCVTIMEO值时,从long值构建struct tv。因此,结果取决于时间分辨率(HZ值)以及算术分割和模数。

相关问题