📄 tcp.lst
字号:
508 3 case TCP_RST | TCP_ACK:
509 3 /* rst: to closed */
510 3 pTCB->TCPState = TCP_STATE_CLOSED;
511 3 TCPRelease(pTCB);
512 3 break;
513 3 }
514 2 break;
515 2 case TCP_STATE_ESTABLISHED:
516 2 /* fin:to closewait send ack */
517 2 if((pTCPHead->flag & TCP_FIN) != 0)
518 2 {
519 3 pTCB->TCPState = TCP_STATE_CLOSEWAIT;
520 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
521 3
522 3 /* call ->close() let user to know he want to close connection
523 3 user should call TCPClose() to close the connection in ->close */
524 3 pTCB->close(pTCB);
525 3 }
526 2 break;
527 2 case TCP_STATE_CLOSEWAIT:
528 2 /* he want to close, send a fin to close */
529 2 pTCB->TCPState = TCP_STATE_LASTACK;
530 2 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT;
531 2 TCPSendSeg(pTCB,TCPAllocate(0), TCP_FIN | TCP_ACK);
532 2 break;
533 2 case TCP_STATE_FINWAIT1:
534 2 switch(pTCPHead->flag)
535 2 {
536 3 case TCP_FIN:
537 3 /* fin: to TCP_STATE_CLOSING send ack */
538 3 pTCB->TCPState = TCP_STATE_CLOSING;
539 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
540 3 break;
541 3 case TCP_FIN | TCP_ACK:
542 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
543 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
544 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
545 3 break;
546 3 case TCP_ACK:
547 3 pTCB->TCPState = TCP_STATE_FINWAIT2;
548 3 break;
549 3 }
550 2 break;
551 2 case TCP_STATE_CLOSING:
C51 COMPILER V7.06 TCP 11/06/2008 08:54:10 PAGE 10
552 2 /* ack:to TCP_STATE_CLOSED */
553 2 if(pTCPHead->flag & TCP_ACK)
554 2 {
555 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
556 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
557 3 }
558 2 break;
559 2 case TCP_STATE_FINWAIT2:
560 2 if(pTCPHead->flag & TCP_FIN)
561 2 {
562 3 pTCB->TCPState = TCP_STATE_TIMEWAIT;
563 3 pTCB->LastAckTimer = TCP_LASTACK_TIME_OUT; /* start timer */
564 3 TCPSendSeg(pTCB,TCPAllocate(0), TCP_ACK);
565 3 }
566 2 break;
567 2 }
568 1
569 1 /*
570 1 * put tcp data to uper layer
571 1 */
572 1 if(TCPDataSize != 0)
573 1 {
574 2 pTCB->recv(MemHead->pStart + TCP_HEAD_LEN(pTCPHead),TCPDataSize);
575 2 }
576 1
577 1 /*
578 1 * free this packet
579 1 */
580 1 MemFree(MemHead);
581 1 }
582
583 /* tcp packet in.*/
584 void TCPInput(struct SMemHead DT_XDATA *MemHead) REENTRANT_SIG
585 {
586 1 struct SIPHead DT_XDATA *pIPHead;
587 1 struct STCPHead DT_XDATA *pTCPHead;
588 1 struct STCB DT_XDATA *pNewTCB;
589 1 struct STCB DT_XDATA *pTCB;
590 1
591 1 pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart);
592 1 pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart - sizeof(struct SIPHead));
593 1
594 1 /*
595 1 * is check sum ok?
596 1 */
597 1 if(TCPCheckSum(pIPHead,ntohs(pIPHead->TotalLen) - IP_HEAD_MIN_LEN) != 0)
598 1 {
599 2 MemFree(MemHead);
600 2 return;
601 2 }
602 1
603 1 /*
604 1 * is there a connection can accept this tcp packet?
605 1 */
606 1
607 1 /* if is syn packet. a tcb in listen can accept it. */
608 1 if(pTCPHead->flag == TCP_SYN)
609 1 {
610 2 for(pTCB = TCBList; pTCB != NULL; pTCB = pTCB->pNext)
611 2 {
612 3 if(pTCB->TCPState == TCP_STATE_LISTEN &&
613 3 pTCB->PortScr == pTCPHead->PortDest)
C51 COMPILER V7.06 TCP 11/06/2008 08:54:10 PAGE 11
614 3 {
615 4 break;
616 4 }
617 3 }
618 2 }
619 1 else
620 1 {
621 2 /* search active connections. TCBState must not the
622 2 closed and listen state */
623 2 for(pTCB = TCBList; pTCB != NULL; pTCB = pTCB->pNext)
624 2 {
625 3 /* and the source ip, dest ip, source port, dest port
626 3 must equal */
627 3 if(pTCB->PortScr == pTCPHead->PortDest &&
628 3 pTCB->PortDest == pTCPHead->PortScr &&
629 3 pTCB->TCPState != TCP_STATE_LISTEN &&
630 3 pTCB->TCPState != TCP_STATE_CLOSED &&
631 3 pTCB->IPScr == pIPHead->IPDest &&
632 3 pTCB->IPDest == pIPHead->IPScr)
633 3 break;
634 3
635 3 }
636 2 }
637 1
638 1 /* can't find, and send a rst */
639 1 if(pTCB == NULL)
640 1 {
641 2 /* allocate a temp tcb for use */
642 2 pNewTCB = TCPSocket(ntohl(pIPHead->IPDest));
643 2 pNewTCB->IPDest = pIPHead->IPScr;
644 2 pNewTCB->PortDest = pTCPHead->PortScr;
645 2 pNewTCB->PortScr = pTCPHead->PortDest;
646 2
647 2 /* set MemFree DataSize to 0 */
648 2 MemHead->pStart = MemHead->pEnd;
649 2
650 2 TCPSendSeg(pNewTCB,TCPAllocate(0),TCP_ACK | TCP_RST);
651 2
652 2 MemFree(MemHead);
653 2 TCPAbort(pNewTCB);
654 2 return;
655 2 }
656 1
657 1 /*
658 1 * is it a expected packet?
659 1 */
660 1 /* first change all necessary part to host order */
661 1 #ifndef HOST_ORDER_AS_NET
pTCPHead->AckSeq = ntohl(pTCPHead->AckSeq);
pTCPHead->Seq = ntohl(pTCPHead->Seq);
pTCPHead->WndSize = ntohs(pTCPHead->WndSize);
#endif
666 1
667 1 /* if it is the first packet from him, don't check sequence.
668 1 in connection case: a syn or syn+ack packet. in listen case
669 1 : a syn packet. so pass all packet contain syn flag */
670 1 if((pTCPHead->flag & TCP_SYN) == 0)
671 1 {
672 2 /* sequence ok? */
673 2 if(pTCB->SeqHis != pTCPHead->Seq)
674 2 {
675 3 /* if this a packet fall within rev window */
C51 COMPILER V7.06 TCP 11/06/2008 08:54:10 PAGE 12
676 3 if(TCP_SEQ_COMPARE(pTCPHead->Seq,pTCB->SeqHis) > 0
677 3 && TCP_SEQ_COMPARE(pTCPHead->Seq,pTCB->SeqHis) < pTCB->WndMine)
678 3 {
679 4 /* write it to QExceedSeq for late receive */
680 4 TCPInsertQ(&(pTCB->QExceedSeq),MemHead,pTCPHead->Seq);
681 4 return;
682 4 }
683 3 else
684 3 {
685 4 /* packet fall outof window, drop it. and send a ack back, because
686 4 this is probably ocurr when our pre send ack is lose.*/
687 4 MemFree(MemHead);
688 4 TCPSendSeg(pTCB,TCPAllocate(0),TCP_ACK);
689 4 return;
690 4 }
691 3 }/* else sequence equal. ok */
692 2 }/* else is syn packet */
693 1
694 1 /* deal incoming packet */
695 1 TCPRecvSeg(pTCB,MemHead);
696 1
697 1 /* if seg in ExceedSeq can receive now? */
698 1 while(pTCB->QExceedSeq != NULL &&
699 1 pTCB->SeqHis == pTCB->QExceedSeq->Seq)
700 1 {
701 2 TCPRecvSeg(pTCB,pTCB->QExceedSeq->MemHead);
702 2 TCPOutQ(&(pTCB->QExceedSeq));
703 2 }
704 1 }
705 /*
706 功能:快速发送数据。在使用 TCPSend 函数时,你首先需要将数据放入 buf 指向的内
707 存中,然后调用 TCPSend 函数,接着该函数会将buf 指向的内存区数据拷贝到TCP 缓冲区
708 中。使用 TCPSendEx()时你首先用TCPAllocate(DATA_SIZE)获得一个 TCP 缓冲区,然后直
709 接将数据放入 TCP 缓冲区中,从而比 TCPSend 函数少一次数据拷贝,提高发送速度。
710
711 数:发送数据的 TCP 连接是套接字指针pTCB 对应的连接,发送的数据放在 TCP 缓
712
713 存 MemHead 中。发送成功返回 TRUE,否则返回FALSE。*/
714
715 BOOL TCPSendEx(struct STCB DT_XDATA * pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
716 {
717 1 /* if state is "closed, listen, syn recvd, syn sent",
718 1 need connected first */
719 1 if(pTCB->TCPState <= TCP_STATE_SYNSENT)
720 1 {
721 2 MemFree(MemHead);
722 2 return FALSE;
723 2 }
724 1
725 1 /* if unsend queue is empty */
726 1 if(pTCB->QUnSend == NULL)
727 1 {
728 2 /* if this packet send completely? */
729 2 if(TCPSendSegJudgeWnd(pTCB,MemHead) == FALSE)
730 2 {
731 3 /* insert the remain for later sending */
732 3 return TCPInsertQ(&(pTCB->QUnSend),MemHead,0);
733 3 }
734 2 else
735 2 return TRUE;
736 2 }
737 1 else
C51 COMPILER V7.06 TCP 11/06/2008 08:54:10 PAGE 13
738 1 return TCPInsertQ(&(pTCB->QUnSend),MemHead,0);
739 1 }
740 /*
741 TCPSend()------------------------------------------------------------
742 功能:发送数据。发送数据的 TCP 连接是套接字指针pTCB 对应的连接,发送的数据
743 的起始地址为buf,大小为 DataSize。发送成功返回 TRUE,否则返回FALSE。 */
744
745 BOOL TCPSend(struct STCB DT_XDATA * pTCB,void DT_XDATA *buf,WORD DataSize) REENTRANT_MUL
746 {
747 1 struct SMemHead DT_XDATA *MemHead;
748 1
749 1 /* allocate */
750 1 if((MemHead = TCPAllocate(DataSize)) == NULL)
751 1 return FALSE;
752 1
753 1 /* copy */
754 1 MemCopy(MemHead->pStart,buf,DataSize);
755 1
756 1
757 1 return TCPSendEx(pTCB,MemHead);
758 1 }
759
760
761 /*
762 TCPConnect()------------------------------------
763 向IP 地址为DestIP的服务器的DestPort 端口发起连接。参数recv 和 close 用于
764 设置当接收到数据包和对方要求关闭 TCP
765 接时应该调用的回调函数指针。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -