?? 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 + -