简体   繁体   English

为什么在WaitForSingleObject之后我的变量不保持状态?

[英]Why aren't my variables holding state after WaitForSingleObject?

I am implementing a Go Back N protocol for a networking class. 我正在为网络课程实现Go Back N协议。 I am using WaitForSingleObject to know when the socket on my receiver thread has data inside it: 我正在使用WaitForSingleObject来了解接收器线程上的套接字何时在其中包含数据:

int result = WaitForSingleObject(dataReady, INFINITE);

For Go Back N, I have to send multiple packets to the receiver at once, and manipulate the data, and then send an ACK packet back to the sender. 对于“返回N”,我必须一次将多个数据包发送到接收方,并处理数据,然后将ACK数据包发送回发送方。 I have a variable expectedSEQ that I increment each time I send an ACK so that I know if a packet arrives out of order. 我有一个变量ExpectedSEQ,每次发送ACK时我都会递增,以便知道数据包是否到达混乱。

However, when the first packet arrives, my debugger tells me that expectedSEQ has been incremented, but when the next packet is being manipulated, expectedSEQ is still its original value. 但是,当第一个数据包到达时,我的调试器会告诉我ExpectedSEQ已经增加,但是当操作下一个数据包时,ExpectedSEQ仍然是其原始值。

Anyone have any idea why this is occurring? 有人知道为什么会这样吗? If I put an if statement as such 如果我这样写一个if语句

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

the second packet registers properly and sends an ack. 第二个数据包正确注册并发送一个ack。 Clearly this will not work for any amount of packets higher than 2 tho. 显然,这对于大于2 tho的任何数量的数据包均不起作用。

I event tried wrapping the entire section (including the original WaitForSingleObject) in a semaphore in an attempt to make everything wait until after the variable was incremented but this didn't work either. 我尝试将整个部分(包括原始的WaitForSingleObject)包装在一个信号量中,以尝试使所有内容都等到变量增加之后,但这也不起作用。

Thanks for your help! 谢谢你的帮助!

Eric 埃里克

Per Request: more 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
}

Exactly how and when do you increment expectedSeq ? 确切地说,如何以及何时增加expectedSeq There may be a memory barrier issue involved, so you might need to access expectedSeq inside a critical section (or protected by some other synchronization object) or use Interlocked APIs to access the variable. 有可能是参与,所以你可能需要访问一个内存屏障问题expectedSeq临界段内(或保护其他一些同步对象),或使用Interlocked API来访问变量。

For example, the compiler might be caching the value of expectedSeq in a register, so synchrnoization APIs might be necessary to prevent that from happening at critical areas of the code. 例如,编译器可能正在expectedSeq ExpectedSeq的值缓存在寄存器中,因此可能需要同步API来防止在代码的关键区域发生这种情况。 Note that using the volatile key word may seem to help, but it's also probably not entirely sufficient (though it might with MSVC, since Microsoft's compiler uses full memory barriers when dealing with volatile objects). 请注意,使用volatile关键字似乎有帮助,但可能还不够用(尽管MSVC可能会用,因为Microsoft的编译器在处理volatile对象时会使用完整的内存屏障)。

I think you'll need to post more code shown exactly how you're handling expectedSeq . 我认为您需要发布更多代码,以准确显示您如何处理expectedSeq

As I was entering my code (hand typing since my code was on another computer), I realized a very stupid bug when I was setting the original value for expectedSeq. 当我输入代码(由于我的代码在另一台计算机上而需要手动键入)时,我在为ExpectedSeq设置原始值时意识到了一个非常愚蠢的错误。 I was setting it to 0 every run through of a packet. 每次运行数据包时,我都将其设置为0。

Have to love the code that comes out when you are coding until 5 am! 不得不爱编码直到凌晨5点才出来的代码!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM