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

📄 net_tcp.c

📁 TI的2812控制交通灯
💻 C
字号:

u8 Wait_1;
u8 Wait_3;
u8 Wait_Exit;

void IP_TCP(void)       //tcp协议处理程序
{

   TCP_Symbol_Receive=Receive_Buffer[Start_TCP+13]&0x3f;  //接收到的TCP标志
   //printf("\nTCP_Symbole_Receive = 0x%4x\n",TCP_Symbol_Receive);

   /*
   0x01   FIN   发端完成发送任务
   0x02   SYN   同步序号用来发起一个连接
   0x04   RST   重建连接
   0x08   PSH   接收方应该尽快将这个报文段交给应用层
   0x10   ACK   确认序号有效
   0x20   URG   紧急指针(urgent pointer)有效*/

   TCP_Port_O=Receive_Buffer[Start_TCP+0]*256+Receive_Buffer[Start_TCP+1];  //外部端口号
   TCP_Port  =Receive_Buffer[Start_TCP+2]*256+Receive_Buffer[Start_TCP+3];  //本地端口号

   TCP_ISN_O =Change_u8_u32(Receive_Buffer,Start_TCP+4);   //外部ISN
   //printf("TCP_ISN_O =%u\n",TCP_ISN_O);

   TCP_ISN_OA=Change_u8_u32(Receive_Buffer,Start_TCP+8);   //外部确认ISN


   Receive_PACK_HTTP_Len=Receive_Buffer[Start_IP+2]*0x100+Receive_Buffer[Start_IP+3]-(Receive_Buffer[Start_TCP+12]/0x10)*4-20;

   switch(TCP_State)
   {
      case 0:  //初始状态,等待被动连接
         if((TCP_Symbol_Receive&0x02)==0x02)  //Symbol = SYN
         {
            TCP_ISN_A=TCP_ISN_O+1;
            TCP_Symbol_Send=0x12;   //SYN,ACK
            Send_TCP_PACK();    //Send SYN,ACK 发送被动连接的第2次握手信号
            TCP_ISN++;
            TCP_State=1;
            Wait_1=0;
         }
         break;
      case 1:  //等待被动连接的第3次握手
         if((TCP_Symbol_Receive&0x10)==0x10)  //Symbol = ACK
            //if(TCP_ISN_OA==ISN);  //被动连接第3次握手信号有效
            TCP_State=2;
		 else
		 {
        	  if(++Wait_1>1)
        	  	TCP_State=0;
         }
         break;
      case 2:  //正常传输状态,或等待被动断开
         if((TCP_Symbol_Receive&0x01)==0x01)  //Symbol = FIN
         {
            TCP_ISN_A=TCP_ISN_O+1;
            TCP_Symbol_Send=0x10;  //ASK
            Send_TCP_PACK();  //发送被动断开的第2次握手信号

            TCP_Symbol_Send=0x11;  //?  似乎可以改成0x01
            Send_TCP_PACK();  //发送被动断开的第3次握手信号
            TCP_ISN++;

            TCP_State=3;
            Wait_3=0;
         }
         else if(TCP_Symbol_Receive&0x04)
         {
         	TCP_State=0;	
         }
         else
         {
            //printf("调用应用处理程序\n");
            if(TCP_Port==80)  //? 按照要求需要判断http包是否是GET请求信号,不仅仅是判断端口
            {
               
               APP_HTTP();    //调用HTTP处理程序
               //Send_HTTP_Response();  //发送HTTP的请求响应包
               //TCP_State=6;
            }
            	
         }
         break;
      case 3:   //在被动断开情况下,等待第4次握手
         if((TCP_Symbol_Receive&0x10)==0x10)  //Symbol = ACK
            //if(TCP_ISN_OA==TCP_ISN);  //判断被动断开情况下,第4次握手是否有效
            TCP_State=0;
         else
         {
         	if(++Wait_3>1)
         		TCP_State=0;
         }
         break;
      case 4:  //在主动断开情况下,等待第2次握手
         if((TCP_Symbol_Receive&0x10)==0x10)  //Symbol = ACK
            //if(TCP_ISN_OA==TCP_ISN);  //判断主动断开情况下,第2次握手信号是否有效
            TCP_State=5;
         break;
      case 5:  //在主动断开情况下,等待第3次握手
         if((TCP_Symbol_Receive&0x01)==0x01)  //Symbol = FIN
         {
            TCP_ISN_A=TCP_ISN_O+1;
            TCP_Symbol_Send=0x10;  //ACK
            Send_TCP_PACK();  //在主动断开情况下,发送第4次握手信号
            TCP_State=0;
         }
         break;
      case 6:  //等待HTTP响应的ACK
         if((TCP_Symbol_Receive&0x10)==0x10)  //Symbol = ACK
         {
            //if(TCP_ISN_OA==TCP_ISN);  //判断http连接中,发送的http头是否被收到
            Send_HTTP_Content();  //发送HTTP内容数据包
            TCP_State=7;
         }
         break;
      case 7:  //等待HTTP内容的ACK
         if((TCP_Symbol_Receive&0x10)==0x10)  //Symbol = ACK
         {
            //if(TCP_ISN_OA==TCP_ISN);  //判断http连接中,发送的http内容是否被收到
            TCP_Symbol_Send=0x01;  //FIN
            TCP_ISN_A=TCP_ISN_O;
            Send_TCP_PACK();  //发送FIN数据包
            TCP_ISN++;
            TCP_State=4;
         }
         break;


   }
   //printf("TCP状态  =  %d\n",TCP_State);
}

void Send_TCP_PACK(void)  //发送TCP连接用的标志数据包
{
   u16 Len=Start_TCP,Bogus_Len=0;
   u16 i,Head_Len;
   u32 Data_SUM;
   u8 TCP_Bogus_Head[12];
   for(i=0;i<2;i++)
      Send_Buffer[Len++]=Receive_Buffer[Len+2];  //16位源端口号
   for(i=0;i<2;i++)
      Send_Buffer[Len++]=Receive_Buffer[Len-2];  //16位目的端口号

   Change_u32_u8(Send_Buffer,Len,TCP_ISN);  //32位序号
   Len+=4;

   Change_u32_u8(Send_Buffer,Len,TCP_ISN_A); //32位确认序号
   Len+=4;



   Send_Buffer[Len++]=Receive_Buffer[Len];  //4位首部长度和前4位保留
   //Send_Buffer[Len++]=0x70;
   //printf("首部长度<<4后的结果  =  %x",Receive_Buffer[Len]);
   Send_Buffer[Len++]=TCP_Symbol_Send;  //后2位保留,6个标志位

   for(i=0;i<2;i++)
      Send_Buffer[Len++]=Receive_Buffer[Len];  //16位窗口大小

   for(i=0;i<2;i++)
      Send_Buffer[Len++]=0;  //16位校验和,先设置为0

   for(i=0;i<2;i++)
      Send_Buffer[Len++]=0;  //16位紧急指针

   Head_Len=(Receive_Buffer[Start_TCP+12]/0x10)*4;
   if(Head_Len>20)
      for(i=0;i<Head_Len-20;i++)
         Send_Buffer[Len++]=Receive_Buffer[Len];  //选项数据

   //设置TCP的伪首部
   for(i=0;i<4;i++)
      TCP_Bogus_Head[Bogus_Len++]=IP_Addr[i];
   for(i=0;i<4;i++)
      TCP_Bogus_Head[Bogus_Len++]=IP_O_Addr[i];
   TCP_Bogus_Head[Bogus_Len++]=0;
   TCP_Bogus_Head[Bogus_Len++]=6;
   TCP_Bogus_Head[Bogus_Len++]=Head_Len/0x100;
   TCP_Bogus_Head[Bogus_Len++]=Head_Len&0xff;

   Data_SUM=CHECK_SUM(TCP_Bogus_Head,0,12)&0xffff;       //伪首部的校验和

   Data_SUM+=CHECK_SUM(Send_Buffer,Start_TCP,Head_Len)&0xffff; //TCP首部校验和

   Data_SUM=(Data_SUM/0x10000)+(Data_SUM&0xffff);
   Data_SUM+=Data_SUM/0x10000;


   Send_Buffer[Start_TCP+16]=(Data_SUM/0x100)&0xff;
   Send_Buffer[Start_TCP+17]=Data_SUM&0xff;

   IP_PACK_Len=Head_Len+20;
   HEAD_IP();   //IP首部

   HEAD_Ethernet();   //以太网首部

   NET_Send_Packet(Send_Buffer,Len);  //发送数据包
}

void Change_u32_u8(u8 *Buffer,u16 Start,u32 Data)   //将一个32位的数据转换成4个8位的数组
{
   Buffer[Start+0]=(Data/0x1000000)&0xff; //32位确认序号
   Buffer[Start+1]=(Data/0x10000)&0xff;
   Buffer[Start+2]=(Data/0x100)&0xff;
   Buffer[Start+3]=Data&0xff;
}

u32 Change_u8_u32(u8 *Buffer,u16 Start)   //数据转换,将4个8位数组转换成一个32位无符号整数
{
   u32 Data;
   Data =Buffer[Start+3];
   Data+=Buffer[Start+2]*0x100;
   Data+=Buffer[Start+1]*0x10000;
   Data+=Buffer[Start+0]*0x1000000;
   return Data;
}




⌨️ 快捷键说明

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