Почему мои переменные не хотят состояния после WaitForsingleObject?

StackOverflow https://stackoverflow.com/questions/4017131

Вопрос

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

int result = WaitForSingleObject(dataReady, INFINITE);

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

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

У кого-нибудь есть идеи, почему это происходит? Если я положил, если утверждение как такое

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

Второй пакетных регистрирует правильно и отправляет ACK. Очевидно, что это не будет работать на любое количество пакетов выше 2 Tho.

Я мероприятие попробовал упаковывать весь раздел (включая оригинальный 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 каждый пробег через пакет.

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top