Почему мои переменные не содержат состояние после WaitForSingleObject? - PullRequest
0 голосов
/ 25 октября 2010

Я реализую протокол Go Back N для сетевого класса.Я использую WaitForSingleObject, чтобы знать, когда сокет в потоке моего приемника содержит данные внутри:

int result = WaitForSingleObject(dataReady, INFINITE);

Для возврата назад N я должен отправлять несколько пакетов получателю одновременно, манипулировать данными изатем отправьте пакет ACK обратно отправителю.У меня есть переменнаяpectedSEQ, которую я увеличиваю каждый раз, когда отправляю ACK, чтобы я знал, приходит ли пакет не по порядку.

Однако, когда приходит первый пакет, мой отладчик сообщает мне, что ожидаемый SEQ был увеличен,но когда манипулируют следующим пакетом, ожидаемое SEQ по-прежнему является его первоначальным значением.

Кто-нибудь знает, почему это происходит?Если я ставлю оператор if как таковой

if(recvHeader->seq == expectedSeq+1)

, второй пакет регистрируется правильно и отправляет подтверждение.Ясно, что это не будет работать для любого количества пакетов, превышающего 2 тыс.

Событие I попыталось обернуть весь раздел (включая исходный WaitForSingleObject) в семафор, пытаясь заставить все ждать, пока переменная не будет увеличенано это тоже не сработало.

Спасибо за вашу помощь!

Эрик

За запрос: больше кода!

WaitForSingleObject(semaphore, INFINITE);
int result = WaitForSingleObject(dataReady, timeout);
if(result == WAIT_TIMEOUT)
   rp->m->printf("Receiver:\tThe packet was lost on the network.\n");
else {
  int bytes = recvfrom(sock, recv_buf, MAX_PKT_SIZE, 0, 0, 0);
  if(bytes > 0) {
   rp->m->printf("Receiver:\tPacket Received\n");
   if(recvHeader->syn == 1 && recvHeader->win > 0)
       windowSize = recvHeader->win;

   //FORMER BUG: (recvHeader->syn == 1 ? expectedSeq = recvHeader->seq : expectedSeq = 0);
   if(recvHeader->syn)
      expectedSeq = recvHeader->seq;
   switch(rp->protocol) {
      case RDT3:
         ...
      break;
      case GBN:
         if(recvHeader->seq == expectedSeq) {
            GBNlastACK = expectedACK;
            //Setup sendHeader for the protocol
            sendHeader->ack = recvHeader->seq;
            ...
            sendto(sock, send_buf, sizeof(send_buf), 0, (struct sockaddr*) &send_addr, sizeof(struct sockaddr_in));
            if(sendHeader->syn == 0) { //make sure its not the first SYN connection packet
               WaitForSingleObject(mutex, INFINITE);
               expectedSeq++;
               ReleaseMutex(mutex);
               if(recvHeader->fin) {
                  fin = true;
                  rp->m->printf("Receiver:\tFin packet has been received. SendingOK\n");
               }          
            }
         }
    break;
    }//end switch
}

Ответы [ 2 ]

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

Когда я вводил свой код (ручная печать, поскольку мой код находился на другом компьютере), я обнаружил очень глупую ошибку, когда устанавливал исходное значение для ожидаемого значения. Я устанавливал его в 0 при каждом проходе пакета.

Должен любить код, который появляется при кодировании до 5 утра!

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

Точно, как и когда вы увеличиваете expectedSeq?Это может быть связано с проблемой барьера памяти, поэтому вам может потребоваться доступ к expectedSeq внутри критической секции (или защищенный каким-либо другим объектом синхронизации) или использование Interlocked API для доступа к переменной.

Например,компилятор может кэшировать значение expectedSeq в регистре, поэтому могут потребоваться API-интерфейсы синхронизации, чтобы этого не происходило в критических областях кода.Обратите внимание, что использование ключевого слова volatile может показаться полезным, но, возможно, этого недостаточно, хотя это может быть и в MSVC, поскольку компилятор Microsoft использует полные барьеры памяти при работе с volatile объектами).

Я думаю, вам нужно будет опубликовать больше кода, показывающего, как именно вы обрабатываете expectedSeq.

...