📄 net_tcp.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 + -