Frage

Ich bin ein Zurück N-Protokoll für eine Vernetzung Klasse implementieren. Ich bin mit WaitForSingleObject zu wissen, wann die Buchse auf meinem Empfänger Thread-Daten im Innern hat:

int result = WaitForSingleObject(dataReady, INFINITE);

Zurück N, habe ich mehrere Pakete an den Empfänger zu senden, und die Daten zu manipulieren, und dann ein ACK-Paket zurück an den Absender schicken. Ich habe eine Variable expectedSEQ, dass ich erhöhe jedes Mal, wenn ich so einen ACK senden, dass ich weiß, ob ein Paket von Ordnung kommt aus.

Wenn jedoch das erste Paket ankommt, mein Debugger sagt mir, dass expectedSEQ erhöht wurde, aber wenn das nächste Paket manipuliert wird, expectedSEQ ist immer noch ihr ursprünglicher Wert.

Wer noch keine Ahnung, warum dies auftritt? Wenn ich lege eine if-Anweisung als solche

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

das zweite Paket registriert ordnungsgemäß und sendet eine ack. Offensichtlich dies nicht funktionieren wird für jede Menge Pakete höher als 2 tho.

I Ereignis versuchte, den gesamten Abschnitt Einwickeln (einschließlich dem Original WaitForSingleObject) in einer Semaphore in einem Versuch, alles warten zu lassen, bis die Variable erhöht wurde, aber das hat nicht funktioniert entweder.

Vielen Dank für Ihre Hilfe!

Eric

Per Anfrage: mehr Code

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
}
War es hilfreich?

Lösung 2

Als ich meinen Code (Hand eingeben, da mein Code auf einem anderen Computer war) eintreten, erkennen ich einen sehr dummen Fehler, wenn ich den ursprünglichen Wert für expectedSeq einstellen. Ich war es auf 0 jeden Durchlauf eines Pakets festlegen.

Haben Sie den Code lieben, das herauskommt, wenn man bis 05.00 codieren!

Andere Tipps

Wie und wann genau tun Sie Schritt expectedSeq? Es kann eine Speicherbarriere Problem beteiligt sein, so dass Sie den Zugriff auf expectedSeq in einem kritischen Abschnitt benötigen könnten (oder durch ein anderes Synchronisationsobjekt geschützt) oder Verwendung Interlocked APIs die Variable zugreifen zu können.

Zum Beispiel könnte der Compiler das Caching sein, den Wert von expectedSeq in einem Register, so synchrnoization APIs erforderlich sein, dass in kritischen Bereichen des Codes geschieht zu verhindern. Beachten Sie, dass das volatile Schlüsselwort verwenden, um Hilfe zu sein scheint, aber es ist auch wahrscheinlich nicht völlig ausreichend (obwohl es vielleicht mit MSVC, da Microsofts Compiler vollen Speichern Barrieren verwendet, um mit volatile Objekten handelt).

Ich denke, Sie müssen genau angezeigt mehr Code schreiben, wie Sie expectedSeq sind Handhabung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top