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

📄 tcp.c

📁 TI公司的DSP TMS320VC5402开发板的全套资料
💻 C
📖 第 1 页 / 共 3 页
字号:
#include    "cpu_reg.h"
#include	"string.h"
#include	"ip.h"
#include	"tcp.h"

Uint16 MyMAC[] = {0xE002,0xA04C,0x7A7E};	//02-E0-4C-A0-7E-7A
Uint16 MyIP[] =	{0xA8C0,0x0B01};			//192.168.1.11	
Uint16 RemoteIP[] =	{0xA8C0,0x2801};		//192.168.1.40
Uint16 SubnetMask[] = {0xFFFF,0x00FF};		//255.255.255.000
Uint16 GatewayIP[] = {0xA8C0,0x0101};		//192.168.1.1

//variable
Uint16 RemoteMAC[3];                        //48 bit MAC
Uint16 RecdFrameMAC[3];
Uint16 RecdFrameIP[2];
Uint16 TCPRemotePort;
Uint32 TCPSegNr;                            //本次要发送的TCP序号
Uint32 TCPAckNr;                            //本次收到的TCP确认
Uint32 TCPSendNextNr;                       //下次发送的TCP序号
Uint32 TCPSent_UnAck;                       //我的还未得到确认的TCP序号
Uint32 TCPIRSeq;                            //我收到的对方的TCP序号
Uint16 TCPTimeout;     
Uint16 TCPConnected;
Uint16 TCPRxDataLenth;
Uint16 TCPTxDataLenth;
//Uint16 TCPResendSeqNr;                    //需要重新发送的TCP序号
Uint16 TCPResendCount;
Uint16 TCPResendNumFlag;
Uint16 RxTCPDataSuccess;
Uint16 TxSuccessFlag;
Uint16 TxFrameSize;
Uint16 TCPStatus;
Uint16 DestMaxSegSize;
Uint16 RecdIpFrameLenth;
Uint16 TCPActiveOpenFlag;
Uint16 ARPAnswerSuccessFlag;

extern Uint16 TxEthnetFrameBuffer[1518/2];
extern Uint16 RxEthnetFrameBuffer[1518/2];


/***************TCP*******************/

void TCP_Init(void)
{
    TCPTimeout = 0;
    TCPStatus = 0;	//TCP_STATE_LISTEN状态
	TxSuccessFlag = 0;
    TCPConnected = 0;
    TCPResendNumFlag = 0;
    TCPSendNextNr = 0x0000;
    TCPActiveOpenFlag = 0;
    TCPResendCount = 20;
    ARPAnswerSuccessFlag = 0;
}

void Delete_Socket(void)
{
    TCPConnected = 0;   //没有建立连接
    TCPStatus = 0;  //TCP_STATE_LISTEN状态
    TCPResendNumFlag = 0;
//----------    
    TCPSegNr = TCPSegNr + 10;   //本次要发送的TCP序号
	//TCPResendSeqNr = TCPSegNr;
//----------
}

/*
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void TCPActiveOpen(void)	//主动打开
{
    Uint16 CalcCkSum;
    TCPActiveOpenFlag=1;    //主动打开标志置1
    if((TCPStatus == TCP_STATE_CLOSED) || (TCPStatus == TCP_STATE_LISTEN))
	{
        TCPAckNr = 0;                            //要发送的TCP确认号
        TCPSegNr = TCPSendNextNr;                //本次发送的TCP序号,TCP_Init()中TCPSendNextNr=0
		//TCPResendSeqNr = TCPSegNr;             //存储用来重新发送的本次发送的TCP序号
        TCPSent_UnAck = TCPSegNr;                //本次发送之后我还未收到确认的序号
		//SYN报文段不能携带数据,但要消耗掉一个序号,所以TCPSendNexNr要加1
        TCPSendNextNr = TCPSegNr + 1;            //下次要发送的TCP序号           
        DestMaxSegSize = 560;

		//Ethnet MAC帧首部
        memcpy((TxEthnetFrameBuffer + ETH_HEADER_START), &RemoteMAC, 3);		//目的MAC地址
        memcpy((TxEthnetFrameBuffer + ETH_HEADER_START + 3), &MyMAC, 3);		//本机MAC地址
        *(TxEthnetFrameBuffer + ETH_HEADER_START + 6) = SwapWord(Frame_IP);	   	//协议

		//IP首部
        /******************************************
         * 00------04--------08----------------16 *
         * |  版本 | 首部长度|     区分服务    |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 0) = SwapWord(Ip_Edition);	//首部长度的单位是32位字,固定部分是20字节即5位字
		/******************************************
		 * 00----------------------------------16 *
         * |        总长度           |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 1) = SwapWord((IP_HEADER_SIZE + TCP_HEADER_SIZE + 4) * 2);	//总长度:首部和数据之和的长度
		/******************************************
		 * 00----------------------------------16 *
         * |               标识                |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 2) = 0;
		/******************************************
		 * 00----03----------------------------16 *
         * | 标志|            片偏移           |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 3) = 0;
		/******************************************
		 * 00----------------08----------------16 *
         * |     生存时间    |      协议     |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 4) = SwapWord((DEFUALT_TTL << 8) | PROTOCOL_TCP);
		/******************************************
		 * 00----------------------------------16 *
         * |         首部检验和       |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + IP_HEADER_START + 5) = 0;
        memcpy((TxEthnetFrameBuffer + IP_HEADER_START + 6), &MyIP, 2);				//源IP地址
        memcpy((TxEthnetFrameBuffer + IP_HEADER_START + 8), &RemoteIP, 2);			//目的IP地址
        CalcCkSum = CalcCheckSum((TxEthnetFrameBuffer + IP_HEADER_START), IP_HEADER_SIZE, 0, 0);
        if(!CalcCkSum)
        	CalcCkSum=0xFFFF;
        *(TxEthnetFrameBuffer + IP_HEADER_START + 5) = CalcCkSum;   //检验和

		//TCP首部
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 0) = SwapWord(MY_TCP_PORT);		//源端口
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 1) = SwapWord(TCPRemotePort);	//目的端口
        WriteDWord((TxEthnetFrameBuffer + TCP_HEADER_START + 2),TCPSegNr);			//32位序号,本报文段所发送的数据的第一个字节的序号,同步位SYN=1
        WriteDWord((TxEthnetFrameBuffer + TCP_HEADER_START + 4),TCPAckNr);			//32位确认号,其若确认号=N,则表明到序号N-1为止的所有数据都已正确收到
		/******************************************
		 * 00------04------------10------------16 *
         * |数据偏移|    保留    |             |  *
         * ------------------------------------   *
		 ******************************************/
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 6) = SwapWord(0x7000 | TCP_CODE_SYN);	//数据偏移指出TCP报文段的数据起始处距离TCP报文段的起始处有多远,实际就是TCP首部长度
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 7) = SwapWord(1024);				//窗口,指的是发送本报文段的一方的接收窗口,指出了现在允许对方发送的数据量
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 8) = 0;							//检验和
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 9) = 0;							//紧急指针,指出紧急数据的末尾在报文段中的位置
        //TCP选项:最大报文段长度       
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 10) = SwapWord(0x0204);  //kind = 2,一字节;len = 4,一字节
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 11) = SwapWord(MY_MAX_SEG_SIZE);	//TCP报文中的数据字段的最大长度,2字节
        /********************************************
         * Kind     Length    Meaning               *
         * ----     ------    -------               *
         *  0         -       End of option list.   *
         *  1         -       No-Operation.         *
         *  2         4       Maximum Segment Size. *
         ********************************************/
        //This option code may be used between options, for example, to align the beginning of a subsequent option on a word boundary.                 
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 12) = SwapWord(0x0101);
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 13) = SwapWord(0x0101);
        CalcCkSum = CalcCheckSum((TxEthnetFrameBuffer + TCP_HEADER_START), 14, 1, 0);
        if(!CalcCkSum)
        	CalcCkSum = 0xFFFF;
        *(TxEthnetFrameBuffer + TCP_HEADER_START + 8) = CalcCkSum;

        TxFrameSize = ETH_HEADER_SIZE + IP_HEADER_SIZE + 14;
        SendFrame(TxEthnetFrameBuffer, TxFrameSize);
        TCPStatus = TCP_STATE_SYN_SENT;     //进入TCP_STATE_SYN_SENT状态
    }
}

void TCP_Send_Reset(void)
{
    *(TxEthnetFrameBuffer + TCP_HEADER_START + 7) = 0;  //窗口,现在允许对方发送的数据量为0
    Prepare_TCP_Frame(0);
}

/*
void Resend_Packet(void)
{
    Prepare_TCP_Frame(TCP_CODE_SYN);
    TCPResendCount = 20;
}
*/

void Process_Resend_Buff(void)
{
    if(TCPResendCount > 0)
         TCPResendCount--;                //防止TCP死锁
	//if(TCPResendSeqNr < TCPSent_UnAck)
		//TCPResendNumFlag = 0;
    if(!TCPResendCount)     //TCPResendCount = 0
    {
    	TCPResendNumFlag++;
        if(TCPResendNumFlag == TCP_MAX_RE_TXDNUM)   //TCP_MAX_RE_TXDNUM = 8
        	Delete_Socket();            //重传8次不成功,删除socket
        else
         	SendFrame(TxEthnetFrameBuffer,TxFrameSize);          //每200ms重传一次
    }
}

⌨️ 快捷键说明

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