我实现一个返回N协议用于一个网络的类。我使用WaitForSingleObject的,知道什么时候在我的接收器线程的插座有它里面的数据:

int result = WaitForSingleObject(dataReady, INFINITE);

有关,在N,I必须一次为多个数据包发送到接收器,和操作数据,然后发送ACK包发回发送器。我有一个可变expectedSEQ我每次递增我发送ACK这样我知道,如果一个数据包到达的顺序进行。

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

任何人有这是为什么发生的任何想法?如果我把一个if语句这样

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

第二分组正确地注册,并发送一个ACK。显然对于较高的数据包的任何量超过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
}
有帮助吗?

解决方案 2

正如我输入我的代码(手打字因为我的代码是另一台计算机上),我意识到一个非常愚蠢的错误,当我设置expectedSeq原始值。我被它的每一个运行设置为0,通过分组的。

不得不爱说出来,当你编码,直到凌晨5点的代码!

其他提示

究竟如何和你增量expectedSeq什么时候?有可能是一个存储器屏障问题涉及,因此可能需要访问expectedSeq临界区内部(或通过某些其它同步对象保护)或使用Interlocked API来访问该变量。

例如,编译器可以是缓存在寄存器expectedSeq的值,所以synchrnoization的API可能是必要的,以防止从在代码的关键区域发生。请注意,使用volatile关键字可能没什么帮助,但它也可能不是完全足够(虽然它可能与MSVC,因为微软的编译器volatile对象打交道时采用全内存屏障)。

我想你会需要张贴出你究竟是如何处理expectedSeq更多的代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top