Таймер получения сети с разрешением мс - PullRequest
0 голосов
/ 14 октября 2010

В моем сценарии я собираю сетевые пакеты, и если пакеты соответствуют сетевому фильтру, я хочу записать разницу во времени между последовательными пакетами, эта последняя часть не работает. Моя проблема в том, что я не могу получить точные измерения в секунду, независимо от того, какую функцию таймера C я использую. Я пробовал: gettimeofday (), clock_gettime () и clock ().

Я ищу помощи, чтобы выяснить, почему мой временной код не работает должным образом.

Я работаю в среде cygwin. Параметры компиляции: gcc -Wall capture.c -o capture -lwpcap -lrt

Фрагмент кода:

/*globals*/
int first_time = 0;
struct timespec start, end;
double sec_diff = 0;

main() {
  pcap_t *adhandle;
  const struct pcap_pkthdr header;
  const u_char *packet;
  int sockfd = socket(PF_INET, SOCK_STREAM, 0);

      .... (previous I create socket/connect - works fine)

  save_attr = tty_set_raw();

  while (1) {  

    packet = pcap_next(adhandle, &header);     // Receive a packet? Process it
    if (packet != NULL) {
      got_packet(&header, packet, adhandle);
    }

    if (linux_kbhit()) {         // User types message to channel
      kb_char = linux_getch();       // Get user-supplied character
      if (kb_char == 0x03)         // Stop loop (exit channel) if user hits Ctrl+C
        break;
    }
  } 
  tty_restore(save_attr);
  close(sockfd);
  pcap_close(adhandle);
  printf("\nCapture complete.\n");
}

В комплекте:

got_packet(const struct pcap_pkthdr *header, const u_char *packet, pcap_t * p){    ... {

   ....do some packet filtering to only handle my packets, set match = 1
  if (match == 1) {
    if (first_time == 0) {
      clock_gettime( CLOCK_MONOTONIC, &start );
      first_time++;
    }
    else {
      clock_gettime( CLOCK_MONOTONIC, &end );

      sec_diff = (end.tv_sec - start.tv_sec) + ((end.tv_nsec - start.tv_nsec)/1000000000.0);  // Packet difference in seconds

      printf("sec_diff: %ld,\tstart_nsec: %ld,\tend_nsec: %ld\n", (end.tv_sec - start.tv_sec), start.tv_nsec, end.tv_nsec);
      printf("sec_diffcalc: %ld,\tstart_sec: %ld,\tend_sec: %ld\n", sec_diff, start.tv_sec, end.tv_sec);
      start = end;         // Set the current to the start for next match
    }
  }
}

Я записываю все пакеты в Wireshark для сравнения, поэтому я ожидаю, что разница в моем таймере будет такой же, как в Wireshark, однако это никогда не происходит. Мой вывод для tv_sec будет правильным, однако tv_nsec даже не близко. Скажем, разница в Wireshark составляет 0,5 секунды, мой таймер скажет, что разница составляет 1,999989728 секунд.

Ответы [ 2 ]

0 голосов
/ 15 октября 2010

В принципе, вы захотите использовать таймер с более высоким разрешением

Кроме того, я не проверял в libpcap, но я уверен, что libpcap может дать вам время накоторый каждый пакет был получен.В этом случае вам будет ближе всего к тому, что показывает Wireshark.

0 голосов
/ 14 октября 2010

Я думаю, что проблема не в часах, а в том, как вы ждете новых данных. Вы должны использовать функцию опроса, чтобы увидеть, когда у вас есть новые данные из сокета или с клавиатуры. Это позволит вашей программе спать, когда нет новых данных для обработки. Это, вероятно, сделает операционную систему более приятной для вашей программы, когда у нее есть данные для обработки и планирования ее выполнения быстрее. Это также позволяет вам выйти из программы, не дожидаясь поступления следующего пакета. В качестве альтернативы вы можете попытаться запустить вашу программу с действительно высоким приоритетом или приоритетом в реальном времени.

Вам следует рассмотреть возможность получения текущего времени в первом случае после получения пакета, если фильтрация может занять очень много времени. Вы также можете рассмотреть несколько потоков для этой программы, если вы пытаетесь захватить данные в быстрой и загруженной сети. Особенно, если у вас более одного процессора, но вы делаете pritnf с, которые могут блокироваться. Я заметил, что у вас есть функция для установки tty в необработанный режим, который я предполагаю, что стандартный вывод tty. Если вы на самом деле используете последовательный терминал, который может сильно замедлить процесс, но стандартный вывод в xterm также может быть медленным. Вы можете рассмотреть возможность установки stdout для полной буферизации, а не для буферизации строки. Это должно ускорить вывод. (man setvbuf)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...