2010-10-25 3 views
0

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

int result = WaitForSingleObject(dataReady, INFINITE); 

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

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

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

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

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

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

Благодарим за помощь!

Eric

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

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 
} 
+0

Это догадки без дополнительного кода. Мое предположение заключалось бы в том, что код получения пакета и ACK отправляют код с недопустимым использованием 'expectedSEQ' с точки зрения параллелизма. –

ответ

0

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

Имейте в виду код, который появляется, когда вы кодируете до 5 утра!

+0

Отметьте это как решение. – Dialecticus

+0

не может продолжаться до 2 дней после отправки в соответствии с требованиями стека –

0

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

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

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