⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp.lst

📁 51 单片机TCP_IP 协议栈ZLIP源码 单片机上网技术
💻 LST
📖 第 1 页 / 共 4 页
字号:
 239   5                                              TCPRelease(pTCB);
 240   5                                      }
 241   4                                      else
C51 COMPILER V7.07   TCP                                                                   01/14/2009 14:46:37 PAGE 5   

 242   4                                      {
 243   5                                              pTCB->RetranTimes++;
 244   5                                              pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
 245   5                                      }
 246   4                              }
 247   3                              else
 248   3                                      pTCB->RetranTimer--;
 249   3                      }
 250   2              }
 251   1      }
 252          /* when a TCP close, send too much packet but no replay, 
 253          connection fail. TCPIP will call TCPRelease to release packet
 254          and queue, but will not reclaim TCB. in other word user
 255          can use this socket again. */
 256          void TCPRelease(struct STCB DT_XDATA *pTCB) REENTRANT_SIG
 257          {
 258   1              struct SPacketQueue DT_XDATA *pQ;
 259   1      
 260   1              /* reclaim Q, and free packet in queue */
 261   1              while(pQ = TCPOutQ(&(pTCB->QExceedSeq)))
 262   1                      MemFree(pQ->MemHead);
 263   1              while(pQ = TCPOutQ(&(pTCB->QUnacked)))
 264   1                      MemFree(pQ->MemHead);
 265   1              while(pQ = TCPOutQ(&(pTCB->QUnSend)))
 266   1                      MemFree(pQ->MemHead);
 267   1      }
 268          
 269          /* fill a segment and send it,NOTE MemHead->pStart point to TCPData */
 270          BOOL TCPSendSeg(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead,BYTE TCPFlag) REENTRANT_SIG
 271          {
 272   1              struct STCPHead DT_XDATA        *pTCPHead;
 273   1              struct SIPHead  DT_XDATA        *pIPHead;
 274   1              WORD SeqInc;
 275   1      
 276   1              /* mem insufficient? */
 277   1              if(MemHead == NULL)
 278   1                      return FALSE;
 279   1      
 280   1              /* SeqMine increasment */
 281   1              if((TCPFlag & TCP_SYN) || (TCPFlag & TCP_FIN))
 282   1              {
 283   2                      SeqInc = MemHead->pEnd - MemHead->pStart + 1;
 284   2              }
 285   1              else
 286   1              {
 287   2                      SeqInc = MemHead->pEnd - MemHead->pStart;
 288   2              }
 289   1      
 290   1              pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart - sizeof(struct STCPHead));
 291   1              
 292   1              /* fill tcp header */
 293   1              pTCPHead->PortDest              = pTCB->PortDest;
 294   1              pTCPHead->PortScr               = pTCB->PortScr;
 295   1              pTCPHead->Seq                   = htonl(pTCB->SeqMine);
 296   1              pTCPHead->AckSeq                = htonl(pTCB->SeqHis);
 297   1              pTCPHead->TCPHeadLen    = (BYTE)(((BYTE)sizeof(struct STCPHead)/4)<<4);
 298   1              pTCPHead->flag                  = TCPFlag;
 299   1              pTCPHead->WndSize               = htons(pTCB->WndMine = MemFreeSize());
 300   1              pTCPHead->CheckSum              = 0;
 301   1              pTCPHead->UrgentPoint   = 0;
 302   1              
 303   1              /* fill some of IPHead. it will be used to calculate TCPChecksum
C51 COMPILER V7.07   TCP                                                                   01/14/2009 14:46:37 PAGE 6   

 304   1              and as augument passed to IPlayer */
 305   1              pIPHead = (struct SIPHead DT_XDATA *)((BYTE DT_XDATA *)pTCPHead - IP_HEAD_MIN_LEN);
 306   1              pIPHead->IPDest                                 = pTCB->IPDest;
 307   1              pIPHead->IPScr                                  = pTCB->IPScr;
 308   1              pIPHead->Protocol                               = IP_PROTOCOL_TCP;
 309   1              pIPHead->TotalLen                               = htons(MemHead->pEnd - 
 310   1                      MemHead->pStart + TCP_HEAD_MIN_LEN + IP_HEAD_MIN_LEN);  /* pStart point to TCP data */
 311   1              pTCPHead->CheckSum = htons(TCPCheckSum(pIPHead,MemHead->pEnd - MemHead->pStart + TCP_HEAD_MIN_LEN));
 312   1                      
 313   1              /* send packet */
 314   1              MemHead->pStart = (BYTE DT_XDATA *)pIPHead;     /* dec pStart */
 315   1              IPOutput(MemHead);
 316   1              
 317   1              /*
 318   1               * renew tcb 
 319   1               */
 320   1              /* no ack need. because this packet will give a ack to him */
 321   1              pTCB->bNeedAck = FALSE; 
 322   1      
 323   1              pTCB->SeqMine += SeqInc;
 324   1      
 325   1              /* if this packet contant data or is a FIN or SYN packet
 326   1              we write it to unacked queue */
 327   1              if(SeqInc != 0)
 328   1              {
 329   2                      /* if the unacked queue is empty, start timer for this packet */
 330   2                      if(pTCB->QUnacked == NULL)
 331   2                      {
 332   3                              pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
 333   3                              pTCB->RetranTimes = 0;
 334   3                      }
 335   2      
 336   2                      TCPInsertQ(&(pTCB->QUnacked),MemHead,htonl(pTCPHead->Seq));
 337   2              }
 338   1              else
 339   1              {
 340   2                      MemFree(MemHead);
 341   2              }
 342   1              return TRUE;
 343   1      }
 344          
 345          /* judge his wnd if he can receive this packet. send call TCPSendSeg.
 346          only send this seg completely return TRUE*/
 347          BOOL TCPSendSegJudgeWnd(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
 348          {
 349   1              struct SMemHead DT_XDATA *NewMemHead;
 350   1              
 351   1              /* if WndHis is large enough to receive this packet send it.
 352   1              otherwise create a new packet and send part of Data. the remain
 353   1              going to transmit when WndHis refresh at TCPInput */
 354   1              if(MemHead->pEnd - MemHead->pStart > pTCB->WndHis)
 355   1              {
 356   2                      /* part of Data need send */
 357   2                      if(pTCB->WndHis > 0)
 358   2                      {
 359   3                              /* create a new MemHead */
 360   3                              if((NewMemHead = TCPAllocate(pTCB->WndHis)) == NULL)
 361   3                                      return FALSE;
 362   3              
 363   3                              /* copy part of data to new MemHead */
 364   3                              MemCopy(NewMemHead->pStart,MemHead->pStart,pTCB->WndHis);
 365   3      
C51 COMPILER V7.07   TCP                                                                   01/14/2009 14:46:37 PAGE 7   

 366   3                              /* delete this part from old MemHead */
 367   3                              MemHead->pStart += pTCB->WndHis;
 368   3      
 369   3                              /* send the NewMemHead */
 370   3                              TCPSendSeg(pTCB,NewMemHead,TCP_ACK);
 371   3      
 372   3                              return FALSE;
 373   3                      }
 374   2                      else
 375   2                      {
 376   3                              /* can't send any data now */
 377   3                              return FALSE;
 378   3                      }
 379   2              }
 380   1              else
 381   1              {
 382   2                      TCPSendSeg(pTCB,MemHead,TCP_ACK);
 383   2                      return TRUE;
 384   2              }
 385   1      }
 386          
 387          /* send seg in unsend queue untill can't send any more. if send all
 388          seg in queue return true */
 389          BOOL TCPSendUnsendQ(struct STCB DT_XDATA *pTCB) REENTRANT_MUL
 390          {
 391   1              /* send every packet in unsend queue if can */
 392   1              for(;pTCB->QUnSend != NULL;)
 393   1              {
 394   2                      /* send it completely? */
 395   2                      if(TCPSendSegJudgeWnd(pTCB,pTCB->QUnSend->MemHead) == TRUE)
 396   2                      {
 397   3                              /* delete it from unsend queue */
 398   3                              TCPOutQ(&(pTCB->QUnSend));
 399   3                      }
 400   2                      else
 401   2                      {
 402   3                              /* only part of the seg is send */
 403   3                              return FALSE;
 404   3                      }
 405   2              }
 406   1              return TRUE;
 407   1      }
 408          
 409          /* call by TCPInput after judge this packet can be received.NOTE:MemHead-pStart point 
 410          to TCP head. TCPHead byte order is change in TCPInput */
 411          void TCPRecvSeg(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_SIG
 412          {
 413   1              WORD TCPDataSize;
 414   1              struct STCB DT_XDATA *pNewTCB;
 415   1              struct SIPHead  DT_XDATA *pIPHead;
 416   1              struct STCPHead DT_XDATA *pTCPHead;
 417   1      
 418   1              pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart );
 419   1              pIPHead  = (struct SIPHead  DT_XDATA *)(MemHead->pStart - IP_HEAD_MIN_LEN);
 420   1      
 421   1              /*
 422   1               * begain renew tcb values
 423   1               */
 424   1      
 425   1              /* dest windows size renew.*/
 426   1              pTCB->WndHis = pTCPHead->WndSize;
 427   1      
C51 COMPILER V7.07   TCP                                                                   01/14/2009 14:46:37 PAGE 8   

 428   1              /* after dest windows renew is it possible to send a packet in unsend queue now ?*/
 429   1              TCPSendUnsendQ(pTCB);
 430   1                      
 431   1              /* His Sequence renew */
 432   1              TCPDataSize = ntohs(pIPHead->TotalLen) - IP_HEAD_MIN_LEN 
 433   1                      - TCP_HEAD_LEN(pTCPHead);
 434   1              if((pTCPHead->flag & TCP_SYN)  || (pTCPHead->flag & TCP_FIN))
 435   1              {
 436   2                      pTCB->SeqHis += TCPDataSize + 1;
 437   2              }
 438   1              else
 439   1              {
 440   2                      pTCB->SeqHis += TCPDataSize;
 441   2              }
 442   1      
 443   1              /* NeedAck? */
 444   1              if(TCPDataSize != 0)
 445   1              {
 446   2                      pTCB->bNeedAck = TRUE;
 447   2                      pTCB->DelayAckTimer = TCP_DELAY_ACK_TIME_OUT;
 448   2              }
 449   1              
 450   1              /* if This packet acked packet in unacked queue */
 451   1              if((pTCPHead->flag & TCP_ACK) != 0)
 452   1              {       
 453   2                      while(pTCB->QUnacked != NULL &&
 454   2                              TCP_SEQ_COMPARE(pTCB->QUnacked->Seq,pTCPHead->AckSeq) < 0)
 455   2                      {
 456   3                              MemFree(pTCB->QUnacked->MemHead); 
 457   3                              TCPOutQ(&(pTCB->QUnacked));     
 458   3                              
 459   3                              /* timer for retran restore */
 460   3                              pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
 461   3                              pTCB->RetranTimes = 0;
 462   3                      }
 463   2              }
 464   1              
 465   1              /*
 466   1               * deal refer to tcb.state and tcp flag
 467   1               */
 468   1              switch(pTCB->TCPState)
 469   1              {
 470   2              case TCP_STATE_CLOSED:
 471   2                      break;
 472   2              case TCP_STATE_LISTEN:
 473   2                      /* syn: to TCP_STATE_SYNSENT, send syn+ack */
 474   2                      if(pTCPHead->flag == TCP_SYN)
 475   2                      {
 476   3                              /* create a new tcb and it is going to deal with 
 477   3                              this connection. */
 478   3                              if((pNewTCB = TCPSocket(htonl(pTCB->IPScr))) == NULL)
 479   3                              {
 480   4                                      MemFree(MemHead);
 481   4                                      return;
 482   4                              }
 483   3      

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -