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

发布于 2024-09-29 04:03:39 字数 2153 浏览 1 评论 0原文

我正在为网络类实现 Go Back N 协议。我正在使用 WaitForSingleObject 来了解接收器线程上的套接字何时在其中包含数据:

int result = WaitForSingleObject(dataReady, INFINITE);

对于 Go Back N,我必须一次向接收器发送多个数据包,并操作数据,然后将 ACK 数据包发送回发送者。我有一个变量 ExpectedSEQ,每次发送 ACK 时都会递增该变量,以便我知道数据包是否按顺序到达。

然而,当第一个数据包到达时,我的调试器告诉我,expectedSEQ 已增加,但当操作下一个数据包时,expectedSEQ 仍然是其原始值。

任何人都知道为什么会发生这种情况?如果我这样放置 if 语句,

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

第二个数据包将正确注册并发送确认。显然,这对于任何数量高于 2 的数据包都不起作用。

我尝试将整个部分(包括原始的 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
}

I am implementing a Go Back N protocol for a networking class. I am using WaitForSingleObject to know when the socket on my receiver thread has data inside it:

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. 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.

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.

Anyone have any idea why this is occurring? If I put an if statement as such

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

the second packet registers properly and sends an ack. Clearly this will not work for any amount of packets higher than 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.

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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三生殊途 2024-10-06 04:03:39

究竟如何以及何时增加 expectedSeq ?可能涉及内存屏障问题,因此您可能需要访问关键部分内的 expectedSeq(或受其他同步对象保护)或使用 Interlocked API 来访问多变的。

例如,编译器可能会将 expectedSeq 的值缓存在寄存器中,因此可能需要同步 API 来防止在代码的关键区域发生这种情况。请注意,使用易失性关键字可能看起来有帮助,但它也可能并不完全足够(尽管它可能与MSVC一起使用,因为微软的编译器在处理易失性时使用完整的内存屏障> 对象)。

我认为您需要发布更多代码来准确显示您如何处理 expectedSeq

Exactly how and when do you increment 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.

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. 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).

I think you'll need to post more code shown exactly how you're handling expectedSeq.

染年凉城似染瑾 2024-10-06 04:03:39

当我输入代码时(因为我的代码在另一台计算机上,所以需要手动输入),当我设置预期序列的原始值时,我意识到一个非常愚蠢的错误。每次数据包运行时我都将其设置为 0。

一定要喜欢凌晨 5 点编码时输出的代码!

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. I was setting it to 0 every run through of a packet.

Have to love the code that comes out when you are coding until 5 am!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文