?? tcp.c
字號(hào):
/*********************************************************************
* Copright(c) 2003,廣州周立功單片機(jī)發(fā)展有限公司
* All rights reserved.
*
*文件名稱: tcp.c
*文件標(biāo)識(shí):
*摘 要: 在事件的驅(qū)動(dòng)下,按照狀態(tài)轉(zhuǎn)移圖進(jìn)行TCP協(xié)議的處理
*
*當(dāng)前版本: V1.0
*完成日期: 2003.2.28
*
*
*********************************************************************/
#define TCP_GLOBALS
#include "net_cfg.h"
/*****************************************************************
**函數(shù)原型: void TCP1024_Init()
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 初始化任務(wù)控制塊,使本地機(jī)進(jìn)入listen狀態(tài)并清空重發(fā)緩沖區(qū)
******************************************************************/
void TCP1024_Init()
{
TCP1024.State=0;
TCP1024.My_Port=MY_TCP_PORT;
TCP1024.Send_Next=0x0000;
Resend_Buff.EtherFrame.RecStatus=0;//表示該重發(fā)緩沖區(qū)沒(méi)有數(shù)據(jù)
}
//==============================================================
/**********************************************************************
**函數(shù)原型: void Send_Reset()
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 發(fā)送TCP_RST數(shù)據(jù)報(bào)文,復(fù)位對(duì)方連接
******************************************************************/
void Send_Reset()
{
uchar i;
for(i=0;i<3;i++)
{
TxdNetBuff.EtherFrame.DestMacId[i]=RxdNetBuff.EtherFrame.SourceMacId[i];//目的網(wǎng)卡地址
}
TxdNetBuff.EtherFrame.NextProtocal=0x0800;//協(xié)議為ip協(xié)議
TxdNetBuff.TcpFrame.SourcePort=RxdNetBuff.TcpFrame.DestPort;
TxdNetBuff.TcpFrame.DestPort=RxdNetBuff.TcpFrame.SourcePort;
TxdNetBuff.TcpFrame.offset=0x50;
TxdNetBuff.TcpFrame.window=0;
TxdNetBuff.TcpFrame.urg=0;
TxdNetBuff.TcpFrame.Crc=0;
TxdNetBuff.IpFrame.DestId[0]=RxdNetBuff.IpFrame.SourceIp[0];
TxdNetBuff.IpFrame.DestId[1]=RxdNetBuff.IpFrame.SourceIp[1];
TxdNetBuff.IpFrame.SourceIp[0]=My_Ip_Address.words[0];
TxdNetBuff.IpFrame.SourceIp[1]=My_Ip_Address.words[1];
TxdNetBuff.IpFrame.ttl=0;
TxdNetBuff.IpFrame.NextProtocal=6;//tcp
TxdNetBuff.IpFrame.Crc=20;
TxdNetBuff.TcpFrame.Crc=CreateTcpCrc();
Create_Ip_Frame(20,RxdNetBuff.IpFrame.SourceIp[0],RxdNetBuff.IpFrame.SourceIp[1],6);
}
/**********************************************************************
**函數(shù)原型: void Tcp_Listen( )
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 本地機(jī)進(jìn)入listen狀態(tài),可以對(duì)TCP_SYN或TCP_FIN請(qǐng)求進(jìn)行處理
******************************************************************/
void Tcp_Listen()
{
uchar i;
/*if(RxdNetBuff.TcpFrame.control&(TCP_FIN))//reset
{Send_Reset();} //對(duì)方不接受請(qǐng)求,
else*/
if(RxdNetBuff.TcpFrame.control&TCP_SYN)//表示這是一個(gè)請(qǐng)求連接
{
for(i=0;i<2;i++) //對(duì)方的ip地址
{TCP1024.Dest_Ip[i]=RxdNetBuff.IpFrame.SourceIp[i];}
for(i=0;i<3;i++) //對(duì)方的以太網(wǎng)地址或網(wǎng)關(guān)地址
{TCP1024.Dest_Mac_Id[i]=RxdNetBuff.EtherFrame.SourceMacId[i];}
TCP1024.My_Port=MY_TCP_PORT; //本機(jī)端口
TCP1024.Dest_Port=RxdNetBuff.TcpFrame.SourcePort;//對(duì)方端口
TCP1024.IRS=RxdNetBuff.TcpFrame.SeqNum; //對(duì)方的初始化順序號(hào)
TCP1024.Rcv_Next=RxdNetBuff.TcpFrame.SeqNum+1; //對(duì)方的順序號(hào),用于確認(rèn)
TCP1024.ISS=TCP1024.Send_Next; //我的初始化順序號(hào)
TCP1024.Sent_UnAck=TCP1024.ISS; //我的未確認(rèn)得序號(hào)
TCP1024.Send_Next=TCP1024.ISS+1; //我的順序號(hào),用于發(fā)送
TCP1024.My_Wl1=RxdNetBuff.TcpFrame.SeqNum; //seq
TCP1024.My_Wl2=TCP1024.Send_Next; //
TCP1024.Rcv_Window=RxdNetBuff.TcpFrame.window; //對(duì)方的WINDOW大小
TCP1024.Snd_Window=1024; //通知對(duì)方本地最大接收1024字節(jié)的包,用于流控
TCP1024.Dest_Max_Seg_Size=560; //默認(rèn)為560
if(RxdNetBuff.TcpFrame.offset>20)
if(RxdNetBuff.TcpFrame.tcpdata[0]==0x02)
if(RxdNetBuff.TcpFrame.tcpdata[1]==0x04) //0204為最大segment選項(xiàng)
{
TCP1024.Dest_Max_Seg_Size=RxdNetBuff.TcpFrame.tcpdata[2]*256+RxdNetBuff.TcpFrame.tcpdata[3];
}
TCP1024.My_Max_Seg_Size=1460;//本地機(jī)可以接受最大的以太網(wǎng)數(shù)據(jù)包
//===========以下建立應(yīng)答幀
for(i=0;i<3;i++)//目的網(wǎng)卡地址
{TxdNetBuff.EtherFrame.DestMacId[i]=TCP1024.Dest_Mac_Id[i];}
TxdNetBuff.EtherFrame.NextProtocal=0x0800;//協(xié)議為ip協(xié)議
TxdNetBuff.TcpFrame.SourcePort=TCP1024.My_Port;
TxdNetBuff.TcpFrame.DestPort=TCP1024.Dest_Port;
TxdNetBuff.TcpFrame.SeqNum=TCP1024.ISS;
TxdNetBuff.TcpFrame.AckNum=TCP1024.Rcv_Next;
TxdNetBuff.TcpFrame.offset=0x70;
TxdNetBuff.TcpFrame.control=0x12; //syn+ack
TxdNetBuff.TcpFrame.window=TCP1024.Snd_Window;
TxdNetBuff.TcpFrame.urg=0;
TxdNetBuff.TcpFrame.Crc=0;
TxdNetBuff.IpPacket.IpPacket[20]=0x0204;//tcp選項(xiàng)
TxdNetBuff.IpPacket.IpPacket[21]=TCP1024.My_Max_Seg_Size;
TxdNetBuff.IpPacket.IpPacket[22]=0x0101;
TxdNetBuff.IpPacket.IpPacket[23]=0x0101;
TxdNetBuff.IpFrame.DestId[0]=TCP1024.Dest_Ip[0];
TxdNetBuff.IpFrame.DestId[1]=TCP1024.Dest_Ip[1];
TxdNetBuff.IpFrame.SourceIp[0]=My_Ip_Address.words[0];
TxdNetBuff.IpFrame.SourceIp[1]=My_Ip_Address.words[1];
TxdNetBuff.IpFrame.ttl=0;
TxdNetBuff.IpFrame.NextProtocal=6;//tcp
TxdNetBuff.IpFrame.Crc=28;
TxdNetBuff.TcpFrame.Crc=CreateTcpCrc();
Create_Ip_Frame(28,TCP1024.Dest_Ip[0],TCP1024.Dest_Ip[1],6);
TCP1024.State=TCP_STATE_SYN_RCVD;//Tcp_SYN_Rec;
}
else if(RxdNetBuff.TcpFrame.control&TCP_RST)
{;}
else
{Send_Reset();}
}
/**********************************************************************
**函數(shù)原型: void Delete_Socket()
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 撤銷(xiāo)本地連接,并清空重發(fā)緩沖區(qū)
******************************************************************/
void Delete_Socket()
{
TcpConnected=0;
TCP1024.State=0;
TCP1024.ISS=TCP1024.ISS+10;//
Resend_Buff.EtherFrame.RecStatus=0;//表示該重發(fā)緩沖區(qū)沒(méi)有數(shù)據(jù)
Printf_String("Disconnect!\r\n");
}
/**********************************************************************
**函數(shù)原型: void Resend_Packet( )
**入口參數(shù): uchar i
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 重發(fā)出錯(cuò)的數(shù)據(jù)包
******************************************************************/
void Resend_Packet()
{
uint ii;
uchar xdata *txd=&TxdNetBuff;
uchar xdata *rt;
rt=&Resend_Buff.bytes.bytebuf;
for(ii=0;ii<Resend_Buff.ResendFrame.length+4;ii++)
{
(*txd)=(*rt);
rt++;
txd++;
}
Send_Packet(&TxdNetBuff,Resend_Buff.ResendFrame.length);
Resend_Buff.ResendFrame.timeout=RtTime;
}
/**********************************************************************
**函數(shù)原型: void Process_Resend_Buff( )
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 根據(jù)接收數(shù)據(jù)的序號(hào)以及超時(shí)時(shí)間對(duì)重發(fā)緩沖區(qū)的數(shù)據(jù)進(jìn)行處理
******************************************************************/
void Process_Resend_Buff()
{
if(Resend_Buff.ResendFrame.timeout>0)
Resend_Buff.ResendFrame.timeout--; //數(shù)據(jù)報(bào)的重發(fā)次數(shù)減一,防止TCP死鎖
if(Resend_Buff.EtherFrame.RecStatus!=0) //表示需要重發(fā)緩沖區(qū)的數(shù)據(jù)
{
if(Resend_Buff.TcpFrame.SeqNum<TCP1024.Sent_UnAck)
//下一個(gè)待發(fā)送的數(shù)據(jù)的序號(hào)應(yīng)該大于TCP1024.Sent_UnAck,因?yàn)? //tcp1024.snd_una表示上一個(gè)已發(fā)送的數(shù)據(jù)字節(jié)的序號(hào),如果
//重發(fā)緩沖區(qū)的數(shù)據(jù)對(duì)應(yīng)的序號(hào)小于TCP1024.Sent_UnAck,則說(shuō)明數(shù)據(jù)
//已正確發(fā)送了,重發(fā)緩沖區(qū)內(nèi)的備份的數(shù)據(jù)就沒(méi)有用了,因此
//這個(gè)數(shù)據(jù)包已經(jīng)過(guò)期了,可以拋棄掉,將緩沖區(qū)置為無(wú)效。
{Resend_Buff.ResendFrame.RtStatus=0;}//該緩沖區(qū)無(wú)效
else if(Resend_Buff.ResendFrame.timeout==0)//超時(shí),或重發(fā)次數(shù)到
{//如果重發(fā)緩沖區(qū)的數(shù)據(jù)包的序號(hào)大于等于未或確認(rèn)的數(shù)據(jù)序號(hào)時(shí)待發(fā)送重發(fā)
Resend_Buff.ResendFrame.RtStatus++;//重發(fā)次數(shù)加一
if(Resend_Buff.ResendFrame.RtStatus==TCP_MAX_RETXD)
{ //重發(fā)TCP_MAX_RETXD次都無(wú)法正確發(fā)送時(shí),撤銷(xiāo)本地連接
Delete_Socket();
}
else //繼續(xù)重發(fā)
Resend_Packet();
}
}
}
/**********************************************************************
**函數(shù)原型: void Tcp_SYN_Sent( )
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值: 無(wú)
**功能說(shuō)明: 本地機(jī)主動(dòng)發(fā)送SYN后,即可進(jìn)入本狀態(tài),該狀態(tài)下,
** : 可接收幾種數(shù)據(jù):tcp_rst或tcp_syn或tcp_syn+tcp_ack
******************************************************************/
void Tcp_SYN_Sent()
{
unsigned char i;
if(((RxdNetBuff.TcpFrame.AckNum<=TCP1024.ISS)||(RxdNetBuff.TcpFrame.AckNum>TCP1024.Send_Next))
&&(RxdNetBuff.TcpFrame.control&TCP_ACK))
{ //對(duì)方發(fā)回的確認(rèn)號(hào)應(yīng)是我的初始化序號(hào)加1,若比我的初始化序號(hào)小
//或大于我的下一個(gè)序號(hào),則說(shuō)明對(duì)方連接出錯(cuò)
if(!(RxdNetBuff.TcpFrame.control&TCP_RST))
{//對(duì)方不接受請(qǐng)求
TxdNetBuff.TcpFrame.SeqNum=RxdNetBuff.TcpFrame.AckNum;
TxdNetBuff.TcpFrame.AckNum=0;
TxdNetBuff.TcpFrame.control=TCP_RST;
Send_Reset();//復(fù)位對(duì)方連接
}
else//對(duì)方發(fā)來(lái)復(fù)位請(qǐng)求,因此撤銷(xiāo)本地的連接
{Delete_Socket();}
}
else if(RxdNetBuff.TcpFrame.control&(TCP_SYN))
{
TCP1024.IRS=RxdNetBuff.TcpFrame.SeqNum; //對(duì)方的初始化順序號(hào)
TCP1024.Rcv_Next=RxdNetBuff.TcpFrame.SeqNum+1; //對(duì)方的順序號(hào),我可以用于給對(duì)方確認(rèn)
if(RxdNetBuff.TcpFrame.control&TCP_ACK)
{
TCP1024.Sent_UnAck=RxdNetBuff.TcpFrame.AckNum;//我的未或確認(rèn)得序號(hào)
Process_Resend_Buff();
}
if(TCP1024.Sent_UnAck>=TCP1024.ISS)
{ //表示在一個(gè)由我發(fā)起的三次連接的過(guò)程中,對(duì)方已經(jīng)對(duì)我的連接請(qǐng)求發(fā)回了確認(rèn)
TCP1024.IRS=RxdNetBuff.TcpFrame.SeqNum;
TCP1024.Rcv_Window=RxdNetBuff.TcpFrame.window; //對(duì)方的window大小,表示對(duì)方可以接收的最大數(shù)據(jù)包的大小
TCP1024.Dest_Max_Seg_Size=560;//默認(rèn)為560
if(RxdNetBuff.TcpFrame.offset>20)
if(RxdNetBuff.TcpFrame.tcpdata[0]==0x02)
if(RxdNetBuff.TcpFrame.tcpdata[1]==0x04)//0204為最大segment選項(xiàng)
{
TCP1024.Dest_Max_Seg_Size=RxdNetBuff.TcpFrame.tcpdata[2]*256+RxdNetBuff.TcpFrame.tcpdata[3];
}
//發(fā)送確認(rèn)
//===========以下建立應(yīng)答幀
for(i=0;i<3;i++)//目的網(wǎng)卡地址
{TxdNetBuff.EtherFrame.DestMacId[i]=TCP1024.Dest_Mac_Id[i];}
TxdNetBuff.EtherFrame.NextProtocal=0x0800;//協(xié)議為ip協(xié)議
TxdNetBuff.TcpFrame.SourcePort=TCP1024.My_Port;
TxdNetBuff.TcpFrame.DestPort=TCP1024.Dest_Port;
TxdNetBuff.TcpFrame.SeqNum=TCP1024.Send_Next;
TxdNetBuff.TcpFrame.AckNum=TCP1024.Rcv_Next;
TxdNetBuff.TcpFrame.offset=0x50;
TxdNetBuff.TcpFrame.control=TCP_ACK;
TxdNetBuff.TcpFrame.window=TCP1024.Snd_Window;
TxdNetBuff.TcpFrame.urg=0;
TxdNetBuff.TcpFrame.Crc=0;
TxdNetBuff.IpFrame.DestId[0]=TCP1024.Dest_Ip[0];
TxdNetBuff.IpFrame.DestId[1]=TCP1024.Dest_Ip[1];
TxdNetBuff.IpFrame.SourceIp[0]=My_Ip_Address.words[0];
TxdNetBuff.IpFrame.SourceIp[1]=My_Ip_Address.words[1];
TxdNetBuff.IpFrame.ttl=0;
TxdNetBuff.IpFrame.NextProtocal=6;//tcp
TxdNetBuff.IpFrame.Crc=20;
TxdNetBuff.TcpFrame.Crc=CreateTcpCrc();
Create_Ip_Frame(20,TCP1024.Dest_Ip[0],TCP1024.Dest_Ip[1],6);
TCP1024.State=TCP_STATE_ESTABLISHED;
TcpConnected=1;
Printf_String("\r\nOK,connected.\r\nC:>");
}
else
{//說(shuō)明對(duì)方同時(shí)發(fā)出連接請(qǐng)求
TCP1024.State=TCP_STATE_SYN_RCVD;
//===========下面建立應(yīng)答幀
for(i=0;i<3;i++)//目的網(wǎng)卡地址
{TxdNetBuff.EtherFrame.DestMacId[i]=TCP1024.Dest_Mac_Id[i];}
TxdNetBuff.EtherFrame.NextProtocal=0x0800;//以太網(wǎng)協(xié)議的下層協(xié)議為IP協(xié)議
TxdNetBuff.TcpFrame.SourcePort=TCP1024.My_Port;
TxdNetBuff.TcpFrame.DestPort=TCP1024.Dest_Port;
TxdNetBuff.TcpFrame.SeqNum=TCP1024.Send_Next;
TxdNetBuff.TcpFrame.AckNum=TCP1024.Rcv_Next;
TxdNetBuff.TcpFrame.offset=0x70;
TxdNetBuff.TcpFrame.control=TCP_ACK+TCP_SYN; //TCP_ACK+TCP_SYN
TxdNetBuff.TcpFrame.window=TCP1024.Snd_Window;
TxdNetBuff.TcpFrame.urg=0;
TxdNetBuff.TcpFrame.Crc=0;
TxdNetBuff.IpPacket.IpPacket[20]=0x0204;//有TCP選項(xiàng)
TxdNetBuff.IpPacket.IpPacket[21]=TCP1024.My_Max_Seg_Size;
TxdNetBuff.IpPacket.IpPacket[22]=0x0101;
TxdNetBuff.IpPacket.IpPacket[23]=0x0101;
TxdNetBuff.IpFrame.DestId[0]=TCP1024.Dest_Ip[0];
TxdNetBuff.IpFrame.DestId[1]=TCP1024.Dest_Ip[1];
TxdNetBuff.IpFrame.SourceIp[0]=My_Ip_Address.words[0];
TxdNetBuff.IpFrame.SourceIp[1]=My_Ip_Address.words[1];
TxdNetBuff.IpFrame.ttl=0;
TxdNetBuff.IpFrame.NextProtocal=6;
TxdNetBuff.IpFrame.Crc=28;
TxdNetBuff.TcpFrame.Crc=CreateTcpCrc();
Create_Ip_Frame(28,TCP1024.Dest_Ip[0],TCP1024.Dest_Ip[1],6);
}
}
}
/**********************************************************************
**函數(shù)原型: void Tcp_SYN_Rec( )
**入口參數(shù): 無(wú)
**出口參數(shù): 無(wú)
**返 回 值:
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -