我在Fedora 25上。在下面的测试程序中,我将recv timeout设置为12秒,12345 microsec,setsockopt
。但是当我使用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
[ ~]$
答案 0 :(得分:0)
根据内核sources:设置printf %q
时,将# ask your shell to generate an eval-safe quoted form of your argument list
printf -v rmt_cmd '%q ' bash -c 'cd /tmp; pwd'
# ...and use bash to evaluate that quoted form.
ssh josh-play 'exec bash -s' <<<"$rmt_cmd"
转换为SO_RCVTIMEO
值,对struct tv
值使用算术。另一方面,在检索long
值时,HZ
值由SO_RCVTIMEO
构成。因此,结果取决于时间分辨率(struct tv
值),以及算术除法和模数。