[英]Why aren't my variables holding state after WaitForSingleObject?
我正在为网络课程实现Go Back N协议。 我正在使用WaitForSingleObject来了解接收器线程上的套接字何时在其中包含数据:
int result = WaitForSingleObject(dataReady, INFINITE);
对于“返回N”,我必须一次将多个数据包发送到接收方,并处理数据,然后将ACK数据包发送回发送方。 我有一个变量ExpectedSEQ,每次发送ACK时我都会递增,以便知道数据包是否到达混乱。
但是,当第一个数据包到达时,我的调试器会告诉我ExpectedSEQ已经增加,但是当操作下一个数据包时,ExpectedSEQ仍然是其原始值。
有人知道为什么会这样吗? 如果我这样写一个if语句
if(recvHeader->seq == expectedSeq+1)
第二个数据包正确注册并发送一个ack。 显然,这对于大于2 tho的任何数量的数据包均不起作用。
我尝试将整个部分(包括原始的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
}
确切地说,如何以及何时增加expectedSeq
? 有可能是参与,所以你可能需要访问一个内存屏障问题expectedSeq
临界段内(或保护其他一些同步对象),或使用Interlocked
API来访问变量。
例如,编译器可能正在expectedSeq
ExpectedSeq的值缓存在寄存器中,因此可能需要同步API来防止在代码的关键区域发生这种情况。 请注意,使用volatile
关键字似乎有帮助,但可能还不够用(尽管MSVC可能会用,因为Microsoft的编译器在处理volatile
对象时会使用完整的内存屏障)。
我认为您需要发布更多代码,以准确显示您如何处理expectedSeq
。
当我输入代码(由于我的代码在另一台计算机上而需要手动键入)时,我在为ExpectedSeq设置原始值时意识到了一个非常愚蠢的错误。 每次运行数据包时,我都将其设置为0。
不得不爱编码直到凌晨5点才出来的代码!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.