📄 tcpserver.c
字号:
else if( (tcp_remote_dsz==0)&&(tcp_remote_flag!=0)&&(tcp_remote_flag!=TCP_SYN))
{
TCP_MY_SEQ=tcp_remote_ack; // 处于建立过程的非第一次数据回复
TCP_MY_ACK=tcp_remote_seq+1; // ACK序号值加1
}
else if(tcp_remote_dsz!=0)
{
TCP_MY_SEQ=tcp_remote_ack; // 处于已经建立后数据回复
TCP_MY_ACK=tcp_remote_seq+tcp_remote_dsz; // ACK序号值加收到的数据长度
}
//***以下代码根据目前状态及当前数据,判断执行何种操作***
//A. 通信复位
//B. 已建立连接状态下进行数据接收处理
//C. 进入TCP连接建立过程
//根据状态判断选择执行内容
if ( (tcp_remote_flag&TCP_RST)!=0x00 )
{
//debuG
uart_send('R');
uart_send('S');
uart_send('T');
uart_send(' ');
//debuG
TCP_STATE=TCP_LISTEN; // 如果收到复位标志,则进入TCP_LISTEN状态
tcp_init_sw(1);
}
else if( (TCP_STATE==TCP_ESTABLISHED)&&((tcp_remote_flag&TCP_FIN)==0)&&(tcp_remote_flag!=TCP_SYN ))
{
//debuG
uart_send('D');
uart_send('A');
uart_send('T');
uart_send('S');
uart_send(0x0d);
uart_send(0x0a);
uart_send(0x0d);
uart_send(0x0a);
//debuG
// 这种条件表示收到实质性的数据
tcp_port_handle(); // 如果已建立连接,且收到的不是连接终止信号
// 则进行有效接收数据处理 。。。
//debuG
uart_send(0x0d);
uart_send(0x0a);
uart_send('D');
uart_send('A');
uart_send('T');
uart_send('E');
uart_send(0x0d);
uart_send(0x0a);
uart_send(0x0d);
uart_send(0x0a);
//debuG
}
else
tcp_state_machine(tcp_remote_flag); // 调用TCP STATE转换程序处理
}
//**********************************
//* TCP SERVER数据发送
//**********************************
void tcpserver_send_data(unsigned int data_length,unsigned char hdr_sz,unsigned char flag)
{
unsigned char temp0;
unsigned char temp1;
unsigned int temp2;
unsigned int temp3;
unsigned long temp4;
// 1.ETHERNET部分数据构建,只对MAC进行处理,FRAME TYPE不边
// a.对已收到的ETHERNET数据包目标NAC地址和源MAC地址相互交换
for(temp0=0;temp0<6;temp0++)
{
temp1=read_62256(SRCMAC0+temp0);
write_62256(DESMAC0+temp0,temp1);
}
for(temp0=0;temp0<6;temp0++)
write_62256(SRCMAC0+temp0,SYSMAC[temp0]);
// 2.TCP部分数据构件,大部分参数保存在全局变量中
// a.TCP端口源端口和目的端口互换
temp0=read_62256(TCP_SRC_PORT);
temp1=read_62256(TCP_DES_PORT);
write_62256(TCP_SRC_PORT,temp1);
write_62256(TCP_DES_PORT,temp0);
temp0=read_62256(TCP_SRC_PORT+1);
temp1=read_62256(TCP_DES_PORT+1);
write_62256(TCP_SRC_PORT+1,temp1);
write_62256(TCP_DES_PORT+1,temp0);
// b.设置数据顺序号
write_62256(TCP_SEQ_NO,(TCP_MY_SEQ>>24)&0x000000FF);
write_62256(TCP_SEQ_NO+1,(TCP_MY_SEQ>>16)&0x000000FF);
write_62256(TCP_SEQ_NO+2,(TCP_MY_SEQ>>8)&0x000000FF);
write_62256(TCP_SEQ_NO+3,TCP_MY_SEQ&0x000000FF);
// c.设置数据确认号
write_62256(TCP_ACK_NO,(TCP_MY_ACK>>24)&0x000000FF);
write_62256(TCP_ACK_NO+1,(TCP_MY_ACK>>16)&0x000000FF);
write_62256(TCP_ACK_NO+2,(TCP_MY_ACK>>8)&0x000000FF);
write_62256(TCP_ACK_NO+3,TCP_MY_ACK&0x000000FF);
// d.设置TCP数据头长度
write_62256(TCP_HDR_SZ,hdr_sz<<2); // 20*4=80(0x50) /24*4=96(0x60)
// e.设置FLAG数值
write_62256(TCP_FLAG,flag); // FLAG由上层程序制定
// f.设置TCP数据WINDOW SIZE
write_62256(TCP_WIN_SZ,TCP_MY_MSS>>8); // WINDOW SIZE与最大接收数相同
write_62256(TCP_WIN_SZ+1,TCP_MY_MSS&0X00FF); //
// g.设置CHECKSUM先置0
write_62256(TCP_CSUM,0x00); // checksum先置0
write_62256(TCP_CSUM+1,0x00);
// h.设置URGENT POINT置0
write_62256(TCP_GUR_PT,0x00); // URGENT POINT置0
write_62256(TCP_GUR_PT+1,0x00);
// i.如有OPTION设置(默认设置MSS),如没有跳过
if(hdr_sz!=20)
{
write_62256(TCP_OPTION,2); // OPTION TYPE=2
write_62256(TCP_OPTION+1,4); // OPTION LENGTH=4
write_62256(TCP_OPTION+2,TCP_MY_MSS>>8); // OPTION MSS高8位
write_62256(TCP_OPTION+3,TCP_MY_MSS&0X00FF); // OPTION MSS低8位
}
// j.设置TCP数据包的数据内容,内容长度data_length(<=TCP_MAX_SEND)
// 上层程序负责将数据写入
// k.TCP_CHECK_SUM计算
temp3=data_length+hdr_sz;
temp2=tcp_check_sum(temp3); // tcp checksum计算,数据头+数据
write_62256(TCP_CSUM,temp2>>8);
write_62256(TCP_CSUM+1,temp2&0x00FF);
// 3.IP数据头构建,在原数据基础上修改,修改内容包括TOTAL LENGTH,ID
// a.修改IP头的TOTAL LENGTH数据
temp3=data_length+hdr_sz+20; // TCP+IP总长度
write_62256(IP_TOL_LEN,temp3>>8);
write_62256(IP_TOL_LEN+1,temp3&0X00FF);
// c.修改IP头的16位ID
temp2=read_62256(IP_ID_ADD); // IP头数据中ID标识区数据加1
temp1=read_62256(IP_ID_ADD+1);
temp2=(temp2<<8)+temp1;
temp2=temp2-1;
write_62256(IP_ID_ADD+1,temp2);
write_62256(IP_ID_ADD,temp2>>8);
// d.IP头的16位head checksum置0
write_62256(IP_HDR_CSUM,0x00); // IP头CHECKSUM部分至0x0000
write_62256(IP_HDR_CSUM+1,0x00);
// e.IP地址互换
for(temp0=0;temp0<4;temp0++) // 设置目标IP地址
{
temp1=read_62256(IP_SRC_IP0+temp0);
write_62256(IP_DES_IP0+temp0,temp1);
}
for(temp0=0;temp0<4;temp0++)
write_62256(IP_SRC_IP0+temp0,SYSIP[temp0]); // 设置本机IP地址
// f.修改IP的CHECKSUM
temp2=ip_cal_csum(); // IP头chechsum计算
write_62256(IP_HDR_CSUM+1,temp2);
write_62256(IP_HDR_CSUM,temp2>>8);
//4.数据发送
temp2=20+hdr_sz+data_length; // 注意了...,数据长度要大于46
if(temp2<46) // 不大于46怎么也调不出来
{
temp2=46-temp2;
for(temp0=0;temp0<temp2;temp0++)
write_62256(TCP_SRC_PORT+hdr_sz+data_length+temp0,0x00); // 不够的补上0
}
else temp2=0;
sendpacket(data_length+hdr_sz+0x22+temp2); // 发送数据
}
//************************************
// TCP数据包头CHECKSUM
//************************************
unsigned int tcp_check_sum(unsigned int length)
{
unsigned char temp;
unsigned int i;
unsigned long datah=0x00000000;
unsigned int data=0x0000;
//***TCP CHECK分为两部分,TCP和dumpheader***
//1.以下对TCP数据段进行求和处理
if( (length&0x0001)==0x0000 ) // a1.偶数处理
{
for(i=0;i<length;i=i+2)
{
data=read_62256(i+TCP_SRC_PORT); // 高位数值xxxxabcd
datah=datah+(data<<8); // 形成数值xxxxabcdxxxx
temp=read_62256(i+TCP_SRC_PORT+1);
datah=datah+temp;
//仔细研究一下为什么回出错??????????
//datah=datah+read_62256(i+TCP_SRC_PORT+1); // 形成数值xxxxabcdefgh
}
}
else // a2.奇数处理
{
for(i=0;i<(length-1);i=i+2)
{
data=read_62256(i+TCP_SRC_PORT); // 高位数值xxxxabcd
datah= datah+(data<<8); // 形成数值xxxxabcdxxxx
temp=read_62256(i+TCP_SRC_PORT+1);
datah=datah+temp;
//datah=datah+read_62256(i+TCP_SRC_PORT+1); // 形成数值xxxxabcdefgh
}
data=read_62256(length+TCP_SRC_PORT-1); // 高位数值xxxxabcd
datah=datah+(data<<8); // 形成数值xxxxabcdxxxx
datah=datah+0x00; // 形成数值xxxxabcdefgh
}
//2.对dumpheader部分求和
data=0x0000;
for(i=0;i<8;i=i+2) // b.对源和目的IP地址求和
{
data=read_62256(i+IP_SRC_IP0); // 高位数值xxxxabcd
datah= datah+(data<<8); // 形成数值xxxxabcdxxxx
temp=read_62256(i+IP_SRC_IP0+1);
datah=datah+temp; // 形成数值xxxxabcdefgh
}
datah=datah+length; // c.加上TCP位长度,共有16位
datah=datah+0x0006; // d.加上协议标志,仅有8位
while( ( data=(datah>>16) )!=0x0000 )
{
datah=(datah&0x0000ffff)+data;
}
data=datah&0x0000ffff;
data=0xFFFF-data;
return data;
}
//**********************************
//* TCP端口选择及数据处理
//**********************************
void tcp_port_handle(void)
{
unsigned char data;
unsigned int port; // tcp port
port=read_62256(TCP_DES_PORT); // xxab
port=(port<<8); // abxx
data=read_62256(TCP_DES_PORT+1);
port=port+data; // abcd计算出TCP PORT的值
if(port==80) // http();
{ // 执行具体应用程序
http_handle();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -