Domanda

Io sono l'attuazione di un protocollo Go Back N per una classe di rete. Sto usando WaitForSingleObject di sapere quando la presa sul mio filo ricevitore dispone di dati al suo interno:

int result = WaitForSingleObject(dataReady, INFINITE);

Per Go Back N, devo inviare più pacchetti al ricevitore in una sola volta, e manipolare i dati, e quindi inviare un pacchetto di nuovo ACK al mittente. Ho un expectedSEQ variabile che ho incrementare ogni volta che mando un ACK in modo che io a sapere se un pacchetto arriva fuori uso.

Tuttavia, quando il primo pacchetto arriva, il mio debugger mi dice che expectedSEQ è stato incrementato, ma quando il prossimo pacchetto viene manipolato, expectedSEQ è ancora il suo valore originale.

Qualcuno ha qualche idea del perché questo sta accadendo? Se metto un'istruzione if, come tale

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

il secondo pacchetto registra correttamente e invia un ACK. Chiaramente questo non funzionerà per qualsiasi quantità di pacchetti superiore 2 tho.

I evento provato avvolgendo l'intera sezione (compreso il WaitForSingleObject originale) in un semaforo, nel tentativo di rendere tutto aspettare fino a dopo la variabile è stata incrementata, ma questo non ha funzionato neanche.

Grazie per il vostro aiuto!

Eric

Per Richiesta: leggi codice

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
}
È stato utile?

Soluzione 2

Mentre stavo entrando il mio codice (mano digitando dato che il mio codice era su un altro computer), mi sono reso conto molto stupido errore quando stavo impostando il valore originale per expectedSeq. Mi è stato impostandolo a 0 ogni corsa attraverso di un pacchetto.

amare il codice che viene fuori quando si esegue la codifica fino alle 5!

Altri suggerimenti

Esattamente come e quando si fa expectedSeq incremento? Ci può essere un problema della barriera di memoria coinvolto, quindi potrebbe essere necessario per l'accesso expectedSeq all'interno di una sezione critica (o protetto da qualche altro oggetto di sincronizzazione) o API utilizzo Interlocked di accedere alla variabile.

Ad esempio, il compilatore potrebbe essere cache il valore di expectedSeq in un registro, quindi potrebbe essere necessario API synchrnoization per evitare che questo avvenga in aree critiche del codice. Si noti che usando la parola chiave volatile può sembrare di aiuto, ma è anche probabilmente non del tutto sufficiente (anche se potrebbe con MSVC, dal momento che il compilatore di Microsoft utilizza le barriere memoria piena quando si tratta di oggetti volatile).

Credo che avrete bisogno di pubblicare più codice mostrato esattamente come si sta movimentazione expectedSeq.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top