Почему ioctl (SIOCGSTAMP) иногда возвращает временную метку, которая позже, чем та, которую можно получить через gettimeofday ()? - PullRequest
0 голосов
/ 08 февраля 2019

При работе с 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()?

...