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

📄 tcp2.c

📁 This code is used to TCP/IP connection It is developed by PIC18F452 and all this code is successfull
💻 C
📖 第 1 页 / 共 4 页
字号:


/*********************************************************************
 * Function:        static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h,
 *                                      NODE_INFO* remote)
 *
 * PreCondition:    TCPInit() is already called
 *
 * Input:           h           - TCP Header to be matched against.
 *                  remote      - Node who sent this header.
 *
 * Output:          A socket that matches with given header and remote
 *                  node is searched.
 *                  If such socket is found, its index is returned
 *                  else INVALID_SOCKET is returned.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
static TCP_SOCKET FindMatchingSocket(TCP_HEADER *h, NODE_INFO *remote)
{
    SOCKET_INFO *ps;
    TCP_SOCKET s;
    TCP_SOCKET partialMatch;

    partialMatch = INVALID_SOCKET;

    for ( s = 0; s < MAX_SOCKETS; s++ )
    {
        ps = &TCB[s];
		//putrsUSART("PORT FIND\n");

        if ( ps->smState != TCP_CLOSED )
        {
            if ( ps->localPort == h->DestPort )
            {
					//putrsUSART("PORT Match\n");
                if ( ps->smState == TCP_LISTEN )
                    partialMatch = s;

                if ( ps->remotePort == h->SourcePort &&
                     ps->remote.IPAddr.Val == remote->IPAddr.Val )
                {
                        return s;
                }
            }
        }
    }

    ps = &TCB[partialMatch];

    if ( partialMatch != INVALID_SOCKET &&
         ps->smState == TCP_LISTEN )
    {
        memcpy((void*)&ps->remote, (void*)remote, sizeof(*remote));
        //ps->remote              = *remote;
        ps->localPort           = h->DestPort;
        ps->remotePort          = h->SourcePort;
        ps->Flags.bIsGetReady   = FALSE;
        ps->TxBuffer            = INVALID_BUFFER;
        ps->Flags.bIsPutReady   = TRUE;

		//putrsUSART("TCP Match\n");

        return partialMatch;
    }

    if ( partialMatch == INVALID_SOCKET )
        return UNKNOWN_SOCKET;
    else
        return INVALID_SOCKET;
}






/*********************************************************************
 * Function:        static void SwapTCPHeader(TCP_HEADER* header)
 *
 * PreCondition:    None
 *
 * Input:           header      - TCP Header to be swapped.
 *
 * Output:          Given header is swapped.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
static void SwapTCPHeader(TCP_HEADER* header)
{
    header->SourcePort      = swaps(header->SourcePort);
    header->DestPort        = swaps(header->DestPort);
    header->SeqNumber       = swapl(header->SeqNumber);
    header->AckNumber       = swapl(header->AckNumber);
    header->Window          = swaps(header->Window);
    header->Checksum        = swaps(header->Checksum);
    header->UrgentPointer   = swaps(header->UrgentPointer);
}



/*********************************************************************
 * Function:        static void CloseSocket(SOCKET_INFO* ps)
 *
 * PreCondition:    TCPInit() is already called
 *
 * Input:           ps  - Pointer to a socket info that is to be
 *                          closed.
 *
 * Output:          Given socket information is reset and any
 *                  buffer held by this socket is discarded.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/

/*static*/extern void CloseSocket(SOCKET_INFO* ps)
{
    if ( ps->TxBuffer != INVALID_BUFFER )
    {
        MACDiscardTx(ps->TxBuffer);
        ps->TxBuffer            = INVALID_BUFFER;
        ps->Flags.bIsPutReady   = TRUE;
    }

    ps->remote.IPAddr.Val = 0x00;
    ps->remotePort = 0x00;
    if ( ps->Flags.bIsGetReady )
    {
        MACDiscardRx();
    }
    ps->Flags.bIsGetReady       = FALSE;
//    ps->TimeOut                 = TCP_START_TIMEOUT_VAL;

    ps->Flags.bIsTxInProgress   = FALSE;

    if ( ps->Flags.bServer )
        ps->smState = TCP_LISTEN;
    else
        ps->smState = TCP_CLOSED;
    return;
}



/*********************************************************************
 * Function:        static void HandleTCPSeg(TCP_SOCKET s,
 *                                      NODE_INFO *remote,
 *                                      TCP_HEADER* h,
 *                                      WORD len)
 *
 * PreCondition:    TCPInit() is already called     AND
 *                  TCPProcess() is the caller.
 *
 * Input:           s           - Socket that owns this segment
 *                  remote      - Remote node info
 *                  h           - TCP Header
 *                  len         - Total buffer length.
 *
 * Output:          TCP FSM is executed on given socket with
 *                  given TCP segment.
 *
 * Side Effects:    None
 *
 * Overview:        None
 *
 * Note:            None
 ********************************************************************/
static void HandleTCPSeg(TCP_SOCKET s,
                        NODE_INFO *remote,
                        TCP_HEADER *h,
                        WORD len)
{
    DWORD ack;
    DWORD seq;
    DWORD prevAck, prevSeq;
    SOCKET_INFO *ps;
    BYTE flags;


    flags = 0x00;
    ps = &TCB[s];

    /*
     * Remember current seq and ack for our connection so that if
     * we have to silently discard this packet, we can go back to
     * previous ack and seq numbers.
     */
    prevAck = ps->SND_ACK;			//
    prevSeq = ps->SND_SEQ;			//

    ack = h->SeqNumber ;				//取出受到的TCP包的序列号
    ack += (DWORD)len;					//计算确认号(此次确认号=序列号+数据长度)
    seq = ps->SND_SEQ;					//??????????????

    /*
     * Clear retry counts and timeout tick counter.
     *	设定差错控制
     */
    ps->RetryCount  = 0;
    ps->startTick   = TickGet();
    ps->TimeOut = TCP_START_TIMEOUT_VAL;

    if ( ps->smState == TCP_LISTEN )			//如果处于TCP_LISTEN状态,那么需要被动打开
    {
        MACDiscardRx();
        
        ps->SND_SEQ     = ++ISS;
        ps->SND_ACK     = ++ack;
        seq             = ps->SND_SEQ;
        ++ps->SND_SEQ;
        if ( h->Flags.bits.flagSYN )			//收到SYN包,发送SYN+ACK,进入SYN_RECVD,等待ACK
        {
            /*
             * This socket has received connection request.
             * Remember calling node, assign next segment seq. number
             * for this potential connection.
             */
            memcpy((void*)&ps->remote, (const void*)remote, sizeof(*remote));
            ps->remotePort  = h->SourcePort;

            /*
             * Grant connection request.
             */
            flags           = SYN | ACK;
            ps->smState     = TCP_SYN_RCVD;
            //putrsUSART("TCP LISTEN\n");
            

        }
        else
        {
            /*
             * Anything other than connection request is ignored in
             * LISTEN state.
             */
            flags               = RST;
            seq                 = ack;
            ack                 = h->SeqNumber;
            ps->remote.IPAddr.Val = 0x00;
            //putrsUSART("TCPRST\n"); 
        }

    }
    else				//如果当前TCP不是处于LISTEN状态
    {
        /*
         * Reset FSM, if RST is received.
         */
        if ( h->Flags.bits.flagRST )			//收到的flagRST,TCP复位
        {
            MACDiscardRx();

            CloseSocket(ps);
            //putrsUSART("CLOSEsocket\n");
            return;

        }

        else if ( seq == h->AckNumber )		//收到的ACK等于将要发送的TCP包的seq
        																	//本地发送的ACK是对远端seq的响应
        																	//远端发送的ACK是对本地seq的响应
        {
            if ( ps->smState == TCP_SYN_RCVD )		//如果处于TCP_SYN_RCVD状态
            {
                if ( h->Flags.bits.flagACK )		//处于TCP_SYN_RCVD状态时收到ACK包	
                {
                    ps->SND_ACK = ack;					//本地Socket将要发送的ACK值=本地收到的seq+收到的数据长度
                    ps->RetryCount = 0;
                    ps->startTick = TickGet();
                    ps->smState = TCP_EST;			//状态机切换到“连接建立”状态
                    
                   //putrsUSART("TCP EST\n");

                    if ( len > 0 )
                    {
                        ps->Flags.bIsGetReady   = TRUE;	//本地数据准备好		
                        ps->RxCount             = len;
                        ps->Flags.bFirstRead    = TRUE;
                    }
                    else
                        MACDiscardRx();
                }
                else		//处于TCP_SYN_RCVD状态时,如果收到非ACK包,
                				//那么,将接收到的包丢弃
                {			
                    MACDiscardRx();
                }
            }
            else if ( ps->smState == TCP_SYN_SENT )			//如果本地SOCKET处于TCP_SYN_SENT状态
            {
                if ( h->Flags.bits.flagSYN )			//同时收到的包是同步包
                {
                    ps->SND_ACK = ++ack;					//将要发送的TCP包的ACK
                    if ( h->Flags.bits.flagACK )	//此包既是同步包又是ACK包
                    {
                        flags = ACK;
                        ps->smState = TCP_EST;		//转为建立状态
                        //putrsUSART("TCP EST\n");
                    }
                    else
                    {
                        flags = SYN | ACK;
                        ps->smState = TCP_SYN_RCVD;	//只收到SYN包,也转为SYN_RCVD状态
                        ps->SND_SEQ = ++seq;
                        //putrsUSART("TCPSYNRCVD\n");
                    }

                    if ( len > 0 )
                    {
                        ps->Flags.bIsGetReady   = TRUE;
                        ps->RxCount             = len;
                        ps->Flags.bFirstRead    = TRUE;
                    }
                    else
                        MACDiscardRx();
                }
                else
                {
                    MACDiscardRx();
                }
            }
            else
            {
                if ( h->SeqNumber != ps->SND_ACK )
                {
                    // Discard buffer.
                    MACDiscardRx();
                    return;
                }

                ps->SND_ACK = ack;	//本地Socket将要发送的ACK值=本地收到的seq+收到的数据长度

                if ( ps->smState == TCP_EST )		//如果SOCKET处于“建立状态“
                {
                    if ( h->Flags.bits.flagACK )		//收到ACK包
                    {
                        if ( ps->TxBuffer != INVALID_BUFFER )		//#define INVALID_BUFFER  (0xff)
                        {
                            MACDiscardTx(ps->TxBuffer);
                            ps->TxBuffer            = INVALID_BUFFER;
                            ps->Flags.bIsPutReady   = TRUE;
                        }
                        //putrsUSART("TCP ESTACK\n");
                    }

                    if ( h->Flags.bits.flagFIN )
                    {
                        flags = FIN | ACK;
                        seq = ps->SND_SEQ++;
                        ack = ++ps->SND_ACK;
                        if(h->Flags.bits.flagACK )
                        {
                          CloseSocket(ps);
                        }
                        else 
                        {
                        ps->smState = TCP_LAST_ACK;
                        }
                        //putrsUSART("TCPLASTACK\n");
                    }


                    if ( len > 0 )
                    {
                        if ( !ps->Flags.bIsGetReady )
                        {
                            ps->Flags.bIsGetReady   = TRUE;
                            ps->RxCount             = len;
                            ps->Flags.bFirstRead    = TRUE;

                             // 4/1/02
                            flags = ACK;
                       }
                        else
                        {
                            /*
                             * Since we cannot accept this packet,
                             * restore to previous seq and ack.
                             * and do not send anything back.
                             * Host has to resend this packet when
                             * we are ready.
                             */
                            flags = 0x00;
                            ps->SND_SEQ = prevSeq;
                            ps->SND_ACK = prevAck;

                            MACDiscardRx();
                        }
                    }
                    else
                    {
                        MACDiscardRx();
                    }


                }
                else if ( ps->smState == TCP_LAST_ACK )		//只等待最后一个ACK,不接收别的包
                {
                    MACDiscardRx();					//包已经读进来了,把缓存中的包丢弃			
                    //putrsUSART("TCPLASKCLOSE\n");
                    if ( h->Flags.bits.flagACK )					//等到了ACK,关闭SOCKET		
                    {
                        CloseSocket(ps);
                    }
                }
                else if ( ps->smState == TCP_FIN_WAIT_1 )
                {
                    MACDiscardRx();
                    //putrsUSART("TCP FIN\n");
                    if ( h->Flags.bits.flagFIN )
                    {
                        flags = ACK;
                        ack = ++ps->SND_ACK;
                        if ( h->Flags.bits.flagACK )
                        {
                            CloseSocket(ps);
                            //putrsUSART("end\n");
                        }
                        else
                        {
                            ps->smState = TCP_CLOSING;
                        }
                    }
                }
                else if ( ps->smState == TCP_CLOSING )		//TCP_CLOSING状态,也只是等待一个ACK
                {
                    MACDiscardRx();
                    //putrsUSART("TCP CLOSING\n");
                    if ( h->Flags.bits.flagACK )
                    {
                        CloseSocket(ps);
                    }
                }
            }
        }
        else
        {
            MACDiscardRx();
        }
    }

    if ( flags > 0x00 )
    {   //putrsUSART("SENTTCP\n");
        SendTCP(remote,
                h->DestPort,
                h->SourcePort,
                seq,
                ack,
                flags);
    }
}



⌨️ 快捷键说明

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