ОБНОВЛЕНИЕ: Документация отсутствовала, поэтому я написал ее. Это задокументировано в man 7 socket
в версии 5.06 man-страниц.
Экспериментально , SO_TIMESTAMPNS
работает, и похоже, что он использует CLOCK_REALTIME
.
Следовательно, функция, которая будет использоваться с SO_TIMESTAMPNS
, имеет вид clock_gettime(CLOCK_REALTIME, &tm);
Я не знаю конкретной c документации для нее, но я сделал некоторый эксперимент:
Я написал простой тест сервера и клиента.
На стороне клиента я подключил сокет, указав SOCK_STREAM
и "tcp"
.
Затем я включенная метка времени в нс:
int enable = 1;
if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPNS, &enable,
sizeof(enable)))
goto err;
Затем я подготовил заголовок сообщения:
char buf[BUFSIZ];
char cbuf[BUFSIZ];
struct msghdr msg;
struct iovec iov;
iov.iov_base = buf;
memset(buf, 0, ARRAY_BYTES(buf));
iov.iov_len = ARRAY_BYTES(buf) - 1;
msg.msg_name = NULL;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cbuf;
msg.msg_controllen = ARRAY_BYTES(cbuf);
И получил несколько раз до и после получения сообщения:
struct timespec tm_before, tm_recvmsg, tm_after, tm_msg;
clock_gettime(CLOCK_REALTIME, &tm_before);
usleep(500000);
clock_gettime(CLOCK_REALTIME, &tm_recvmsg);
n = recvmsg(sd, &msg, MSG_WAITALL);
if (n < 0)
goto err;
usleep(1000000);
clock_gettime(CLOCK_REALTIME, &tm_after);
После этого я прочитал метку времени сообщения:
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_TIMESTAMPNS) {
memcpy(&tm_msg, CMSG_DATA(cmsg), sizeof(tm_msg));
break;
}
}
if (!cmsg)
goto err;
и наконец напечатал результаты:
double tdiff;
printf("%s\n", buf);
tdiff = timespec_diff_ms(&tm_before, &tm_recvmsg);
printf("tm_r - tm_b = %lf ms\n", tdiff);
tdiff = timespec_diff_ms(&tm_before, &tm_after);
printf("tm_a - tm_b = %lf ms\n", tdiff);
tdiff = timespec_diff_ms(&tm_before, &tm_msg);
printf("tm_m - tm_b = %lf ms\n", tdiff);
Который напечатал:
asdasdfasdfasdfadfgdfghfthgujty 6, 0;
tm_r - tm_b = 500.000000 ms
tm_a - tm_b = 1500.000000 ms
tm_m - tm_b = 18.000000 ms
Система :
Linux debian 5.4.0-4-amd64 #1 SMP Debian 5.4.19-1 (2020-02-13) x86_64 GNU/Linux
gcc (Debian 9.3.0-8) 9.3.0
Однако я не нашел ни одной справочной страницы, которая бы говорила о SO_TIMESTAMPNS
, так что это может не работать в других системах.
Я не сделал не тестирую SO_TIMESTAMP
потому что это использует struct timeval
, который AFAIK устарел .