2010-10-25 61 views
0

我正在爲網絡類實施Go Back N協議。我使用WaitForSingleObject的,知道什麼時候在我的接收器線程的插座有它裏面的數據:爲什麼我的變量在WaitForSingleObject之後沒有保持狀態?

int result = WaitForSingleObject(dataReady, INFINITE); 

對於返回N,我一定要多包一次發送到接收端,並操縱數據,然後發送一個ACK包返回給發送者。我有一個期望的變量SEQ,每增加一次ACK就會增加一次,這樣我就知道一個數據包是否按順序到達。

但是,當第一個數據包到達時,我的調試器告訴我期望的SEQQ已經增加,但是當下一個數據包被操作時,expectSEQ仍然是其原始值。

任何人都知道爲什麼會發生這種情況?如果我把這樣一個if語句

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

第二個數據包正確註冊併發送ack。顯然,這對任何高於2 th的數據包都不起作用。

我的事件試圖在信號量中包裝整個部分(包括原始的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 
} 
+0

這是猜測沒有更多的代碼。我的猜測是,從併發的角度來看,數據包接收代碼和ACK發送代碼會濫用'expectedSEQ'。 – 2010-10-25 17:27:42

回答

0

當我輸入自己的代碼(手工打字,因爲我的代碼在另一臺計算機上),當我設置expectedSeq的原始值時,我意識到了一個非常愚蠢的錯誤。每運行一個數據包,我就將它設置爲0。

不得不愛編寫代碼直到凌晨5點出現!

+0

將此標記爲解決方案。 – Dialecticus 2010-10-25 18:20:35

+0

不能發佈,直到發佈每個stackoverflow要求後的2天 – 2010-10-26 16:05:31

0

究竟是何時何時增加expectedSeq?可能存在內存屏障問題,因此您可能需要在臨界區內訪問expectedSeq(或受其他同步對象保護),或使用Interlocked API訪問該變量。

例如,編譯器可能會將expectedSeq的值緩存在寄存器中,因此可能需要使用同步API以防止在代碼的關鍵區域發生這種情況。請注意,使用volatile關鍵字似乎有幫助,但它也可能不完全足夠(儘管它可能與MSVC一起使用,因爲Microsoft的編譯器在處理volatile對象時使用全內存障礙)。

我想你需要發佈更多的代碼,顯示你如何處理expectedSeq