Почему ioctl(SIOCGSTAMP) иногда возвращает временную метку, которая позже по сравнению с той, которую можно получить с помощью gettimeofday()?
При работе с UDP-сокетами в Linux (SOCK_DGRAM
), Я заметил странное поведение при попытке получить метки времени приема пакетов через ioctl(..., SIOCGSTAMP, ...)
и с помощью gettimeofday()
вызывается, как только каждый пакет получен.
В частности, при установлении соединения между клиентом и сервером, связывании / прослушивании одного и того же порта, я заметил, что первый пакет всегда демонстрирует такое поведение, а все последующие - нет.
Вот наиболее важный фрагмент кода для получения метки времени получения пакета:
// Receive UDP packet with recvfrom()...
gettimeofday(&rx_timestamp_usr,NULL);
fprintf(stdout,"gettimeofday() (before ioctl()): %lu.%lu\n",rx_timestamp_usr.tv_sec,rx_timestamp_usr.tv_usec);
if(ioctl(args->sData.descriptor,SIOCGSTAMP,&rx_timestamp)==-1) {
// Print error message...
break;
}
gettimeofday(&rx_timestamp_usr,NULL);
fprintf(stdout,"gettimeofday() (after ioctl()): %lu.%lu\n",rx_timestamp_usr.tv_sec,rx_timestamp_usr.tv_usec);
fprintf(stdout,"ioctl: %lu.%lu\n",rx_timestamp.tv_sec,rx_timestamp.tv_usec);
// ...
В качестве вывода при запуске, например, клиента и сервера через интерфейс обратной связи, я вижу что-то вроде этого:
gettimeofday() (before ioctl()): 1549636037.59845
gettimeofday() (after ioctl()): 1549636037.59884
ioctl: 1549636037.59882
gettimeofday() (before ioctl()): 1549636037.69922
gettimeofday() (after ioctl()): 1549636037.69959
ioctl: 1549636037.69844
gettimeofday() (before ioctl()): 1549636037.79890
gettimeofday() (after ioctl()): 1549636037.79926
ioctl: 1549636037.79811
gettimeofday() (before ioctl()): 1549636037.89888
gettimeofday() (after ioctl()): 1549636037.89924
ioctl: 1549636037.89810
gettimeofday() (before ioctl()): 1549636037.99912
gettimeofday() (after ioctl()): 1549636037.99963
ioctl: 1549636037.99759
Как вы можете видеть, пакеты 2-5 показывают ожидаемое поведение, с ioctl
отметка времени всегда раньше, чем отметка времени, полученная благодаря gettimeofday()
,
Вместо этого первый пакет возвращает значение, которое позже по времени относительно того, что я получаю благодаря первому gettimeofday()
вызов.
Почему я замечаю это поведение? не SIOCGSTAMP
возвращать метку времени пакета, как только он получен ядром? Если это так, то почему он возвращает значение, которое позже по сравнению с тем, которое приходит из gettimeofday()
, который называется как минимум 10 строк кода после recvfrom()
?