2015-05-24 3 views
1

Мой профессор дал мне назначение реализовать алгоритм выборочного повторения ARQ в C для пакетной транзакции между отправителем и получателем. Существует таймер, связанный с каждым пакетом, который должен быть отправлен отправителю, который активируется при отправке этого пакета, в соответствии с которым определяется, какой пакетный дубликат необходимо отправить.
Но я не знаю, как установить таймер каждого пакета. Пожалуйста, предложите какой-либо метод для этого.Таймер в селективном повторении ARQ

Спасибо заранее!

ответ

1
  1. Храните структуру данных (например, приоритетную очередь или упорядоченную карту или некоторые такие), которая содержит каждый пакет, который вы планируете (повторно) отправлять, а также время, в которое вы собираетесь (повторно) Отправь это. В идеале эта структура данных будет такова, что эффективно определять наименьшую временную метку в настоящее время в структуре данных, но если количество запланированных пакетов будет относительно небольшим, может работать и более простая неупорядоченная структура данных, такая как связанный список.
  2. На каждой итерации цикла событий определите наименьшее значение временной метки в структуре данных. Вычитайте значение current time из этого значения временной метки, чтобы получить время задержки (в миллисекундах или микросекундах или тому подобное).
  3. Если вы используете select() или подобное, вы можете передать это время задержки в качестве аргумента таймаута. Если вы делаете что-то более простое без мультиплексирования, вы можете уйти с передачей времени задержки на usleep() или подобное вместо этого.
  4. После возврата функции select() (или usleep()) снова проверьте текущее время. Если текущее время больше или равно целевому времени, вы можете отправить пакет с наименьшей временной меткой, а затем удалить его из своей структуры данных. (Если вы считаете, что можете повторно отправить его позже, вы можете снова вставить его в структуру данных с новым/обновленным значением временной метки)
1

Вы также можете использовать Threads для этой цели, что довольно просто и требует меньше строк кодов.

Вам просто нужно создать и определить эту функцию:

unsigned long CALLBACK packetTimer(void *pn){ 

    //This is our Packet Timer 
    //It's going to run on a Tread 
    //If ack[thisPacketNumber] is not true 
    //We gonna check will check for packet time 
    //If it's reached to its limit we gonna send this packet again 
    //and reset the timer 

    //If ack[] becomes true 
    //break the while loop and this will end this tread 
    int pno = (int)pn; 
    std::clock_t start; 
    double duration; 

    start = std::clock(); 

    while(1){ 

     if(!ack[pno]){ 

      duration = (std::clock() - start)/(double) CLOCKS_PER_SEC; 

      if(duration > 0.5){ 
       //This tells that we haven't received our ACk yet for this packet 
       //So send it again 

       printf("SendBuffer for Packet %d: %s", pno, packets[pno]->data); 
       //Resending packet again 
       send_unreliably(s,packets[pno]->data,(result->ai_addr)); 

       //Reseting the timer 
       start = std::clock(); 

      } 

     }else{break;} 

    } 


} 

И внутри вашего цикла в то время, когда вы посылать и принимать пакеты на приемник, вы просто определить:

unsigned long tid;//This should be outside the while loop, 
        //Ideally in the beginning of main function 

CreateThread(NULL,0,packetTimer,(void *)packetNumber,0,&tid); 

Это implementaion является для окон, для UNIX нам нужно использовать pthread()

Это все. И не забывайте добавлять необходимые заголовочные файлы, такие как:

#include <stdlib.h> 
#include <cstdio> 
#include <ctime> 
Смежные вопросы