共2条
1/1 1 跳转至页
tcp,udp,easyarm2200,tcp,ip 用tcp/udp测试工具测试easyarm2200的tcp/ip实验
问
用tcp/udp测试工具创建了一个客户端模式的连接,目标ip是开发板的ip,192.168.0.174,目标端口是80。点击“连接”按钮,pc和目标板只能连接上一下,然后就断开了。每次点击连接都是这样。请问各位高手,这是什么原因?是程序决定的吗?还是设置决定的?应该怎么改才能让它连接以后不断开?
答 1:
re程序决定,修改断开部分的程序
答 2:
请问deeploves能否提示一下是哪部分程序?谢谢!
答 3:
re/*****************************************************************************************
版权所有:
版本号: 1.0.1
生成日期: 2005.1.1
文件名: mE_TCP.C
作者: 影舞者
功能说明: TCP层协议
其它说明:
所属文件关系: 本文件为工程规约代码文件
修改记录:
记录1:
修改者:
修改日期:
修改内容:
修改原因:
*****************************************************************************************/
#define mE_TCP_GLOBALS // 定义全局变量
#include "mE_TCPIP.H" // 以太网文件
#if mE_TCP_FUNC_ENABLE // TCP功能定义
/*****************************************************************************************
函数名称: uint16 mE_TCP_CREATE_HEAD_CRC(uint8 *check,uint16 length)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 计算校验和
输入参数: uint8 *check: 被校验数据起始地址
输出参数: uint16 length: 被校验数据长度,单位字
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP协议层
*****************************************************************************************/
uint16 mE_TCP_CREATE_HEAD_CRC(uint8 *check,uint16 length)
{
uint32 sum = 0, i;
for (i=0;i<(length)/2;i++) // 16位计算
{
sum = sum + ((uint32)check[2*i]<<8)+(uint32)check[2*i+1];
}
if(length&0x0001) // 长度为奇数个时,要进行该操作
{
sum = sum + ((uint32)check[2*i]<<8);
}
sum = (sum&0xffff)+((sum>>16)&0xffff); // 高16位和低16位相加
if(sum & 0xffff0000) // 表示有进位
{
sum++;
}
return ((uint16)(~((sum)&0xffff))); // 数据取反
}
/*****************************************************************************************
函数名称: uint16 mE_TCP_CHECKSUM1(uint8 num,uint16 length)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 计算校验和
输入参数: uint8 num: 被校验数据起始地址
uint16 length: 被校验数据长度,单位字
输出参数: ~((sum)&0xffff))
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint16 mE_TCP_CHECKSUM1(uint8 num,uint16 length)
{
uint16 i;
uint32 sum = 0;
for (i=0;i<6;i++)
{
sum = sum + ((uint32)mE_TCP_SOCKET[num].TcpDHeadUint8[2*i]<<8) + (uint32)mE_TCP_SOCKET[num].TcpDHeadUint8[2*i+1];
}
length = length-12;
i = 0;
while(i<(length/2))
{
sum = sum + ((uint32)mE_TCP_SOCKET[num].TcpHeadUint8[2*i]<<8) + (uint32)mE_TCP_SOCKET[num].TcpHeadUint8[2*i+1];
i++;
}
if(length&0x0001) // 长度为奇数个时,要进行该操作
{
sum = sum + (uint32)(mE_TCP_SOCKET[num].TcpHeadUint8[2*i])*256;
}
sum = (sum&0x0000ffff) + ((sum>>16)&0x0000ffff); // 高16位和低16位相加
if(sum & 0xffff0000)
{ // 表示有进位
sum++;
if(sum & 0xffff0000)
{ // 表示有进位
sum++;
}
}
return ( (uint16)(~((sum)&0xffff)) ); // 注意取反
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_INITIALIZE(void)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 初始化TCP协议
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint8 mE_TCP_INITIALIZE(void)
{
uint8 i;
for(i=0;i<mE_MAX_TCP_LINKS;i++)
{
mE_TCP_SOCKET[i].State = mE_TCP_STATE_CLOSED;
mE_TCP_SOCKET[i].StaSem = 0;
TCP_SEM_SEND_SUCESS[i] = OSSemCreate(0);
TCP_SEM_CONN_SUCESS[i] = OSSemCreate(0);
TCP_SEM_DISC_SUCESS[i] = OSSemCreate(0);
}
mE_TCP_BUFFER.Tcp_Head.Reserve = 0;
mE_TCP_BUFFER.Tcp_Head.NextProtocal = 6;
return 0;
}
/*****************************************************************************************
函数名称: void mE_DELETE_SOCKET(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 如果是非监听状态,则关闭
如果是监听状态,则恢复起始状态
输入参数: uint8 num: 索引值
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议,存在BUG
*****************************************************************************************/
void mE_DELETE_SOCKET(uint8 num)
{
uint16 i;
OS_ENTER_CRITICAL();
if((mE_TCP_SOCKET[num].StaSem&mE_TCP_FOR_LISTEN) == mE_TCP_FOR_LISTEN)
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_LISTEN;
mE_TCP_SOCKET[num].StaSem = mE_TCP_FOR_LISTEN|mE_TCP_WAIT_SEMCONN;
}
else
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_CLOSED;
mE_TCP_SOCKET[num].StaSem = 0;
}
do
{
i = OSSemAccept(TCP_SEM_CONN_SUCESS[num]);
}while(i != 0);
do
{
i = OSSemAccept(TCP_SEM_SEND_SUCESS[num]);
}while(i != 0);
do
{
i = OSSemAccept(TCP_SEM_DISC_SUCESS[num]);
}while(i != 0);
OS_EXIT_CRITICAL();
}
/*****************************************************************************************
函数名称: void mE_TCP_HEAD_HANDLE(uint8 num ,uint16 Tcp_headlength_Control)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 填充TCP报文头及TCP伪报头数据
输入参数: uint8 num : mE_TCP_SOCKET索引号
uint16 Tcp_headlength_Control: 帧头长度、标志
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
void mE_TCP_HEAD_HANDLE(uint8 num ,uint16 Tcp_headlength_Control)
{
// TCP报文头
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
// AckNum;
mE_TCP_SOCKET[num].TcpHeadUint8[8] = (mE_TCP_SOCKET[num].SenPassAck&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[9] = (mE_TCP_SOCKET[num].SenPassAck&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[10] = (mE_TCP_SOCKET[num].SenPassAck&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[11] = (mE_TCP_SOCKET[num].SenPassAck&0x000000ff);
// Offset;
mE_TCP_SOCKET[num].TcpHeadUint8[12] = (Tcp_headlength_Control&0xff00)>>8;
// Control;
mE_TCP_SOCKET[num].TcpHeadUint8[13] = Tcp_headlength_Control&0x00ff;
// Window;
mE_TCP_SOCKET[num].TcpHeadUint8[14] = (mE_TCP_SOCKET[num].Snd_Window&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[15] = mE_TCP_SOCKET[num].Snd_Window&0x00ff;
// Crc;
mE_TCP_SOCKET[num].TcpHeadUint8[16] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = 0;
// Urg;
mE_TCP_SOCKET[num].TcpHeadUint8[18] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[19] = 0;
// 添加TCP伪报头
// Reserve
mE_TCP_SOCKET[num].TcpDHeadUint8[0] = 0;
// NextProtocal
mE_TCP_SOCKET[num].TcpDHeadUint8[1] = 6;
// SourceIp
mE_TCP_SOCKET[num].TcpDHeadUint8[4] = mE_TCP_SOCKET[num].My_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[5] = mE_TCP_SOCKET[num].My_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[6] = mE_TCP_SOCKET[num].My_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[7] = mE_TCP_SOCKET[num].My_Ip[3];
// DestIp
mE_TCP_SOCKET[num].TcpDHeadUint8[8] = mE_TCP_SOCKET[num].Dest_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[9] = mE_TCP_SOCKET[num].Dest_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[10] = mE_TCP_SOCKET[num].Dest_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[11] = mE_TCP_SOCKET[num].Dest_Ip[3];
}
/*****************************************************************************************
函数名称: void mE_TCP_LISTEN(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 收到对方的SYN信息,进入监听处理,返回SYN-ACK
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: mE_TCP_BUFFER.Tcp_Data里16位变量的格式已全部转换完毕
*****************************************************************************************/
void mE_TCP_LISTEN(uint8 num)
{
static uint32 initalseq = 260132451;
struct _pkst TxdData;
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_SYN) // 是同步帧
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP接收SYN同步信号",1);
#endif
// 转换状态,记录数据
mE_TCP_SOCKET[num].State = mE_TCP_STATE_SYN_RCVD; // TCP_STATE_SYN_RCVD
mE_TCP_SOCKET[num].Dest_Port = mE_TCP_BUFFER.Tcp_Data.SourcePort; // 对方端口
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧顺序号
mE_TCP_SOCKET[num].RecPassAck = 0; // 对方此帧应答号
mE_TCP_SOCKET[num].SenPassSeq = initalseq; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq+1; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Snd_Window = mE_MAX_TCP_WINDOW; // 本地的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 对方接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].My_Max_Seg_Size = mE_MAX_TCP_DATA; // 本地接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
mE_TCP_SOCKET[num].TcpDataQWrPtr = 0; // 数据的长度
mE_TCP_SOCKET[num].TcpDataQRdPtr = 0;
// 获取最大的传输段
if(mE_TCP_BUFFER.Tcp_Data.Offset > 50) // 报头大于20字节
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP发送SYN-ACK信号",1);
mE_DEBUG_STRING("\n 发送序列号: ",1);
mE_DEBUG_DEC(mE_TCP_SOCKET[num].SenPassSeq,1);
mE_DEBUG_STRING("\n 发送确认号: ",1);
mE_DEBUG_DEC(mE_TCP_SOCKET[num].SenPassAck,1);
#endif
// 向对方发送SYN-ACK报
// 添加TCP头选项
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
// AckNum;
mE_TCP_SOCKET[num].TcpHeadUint8[8] = (mE_TCP_SOCKET[num].SenPassAck&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[9] = (mE_TCP_SOCKET[num].SenPassAck&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[10] = (mE_TCP_SOCKET[num].SenPassAck&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[11] = (mE_TCP_SOCKET[num].SenPassAck&0x000000ff);
// Offset;
mE_TCP_SOCKET[num].TcpHeadUint8[12] = 0x70;
// Control;
mE_TCP_SOCKET[num].TcpHeadUint8[13] = mE_TCP_SYN|mE_TCP_ACK;
// Window;
mE_TCP_SOCKET[num].TcpHeadUint8[14] = (mE_TCP_SOCKET[num].Snd_Window&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[15] = mE_TCP_SOCKET[num].Snd_Window&0x00ff;
// Crc;
mE_TCP_SOCKET[num].TcpHeadUint8[16] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = 0;
// Urg;
mE_TCP_SOCKET[num].TcpHeadUint8[18] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[19] = 0;
// 选项和填充
mE_TCP_SOCKET[num].TcpHeadUint8[20] = 0x02;
mE_TCP_SOCKET[num].TcpHeadUint8[21] = 0x04;
mE_TCP_SOCKET[num].TcpHeadUint8[22] = mE_MAX_TCP_DATA / 256;
mE_TCP_SOCKET[num].TcpHeadUint8[23] = mE_MAX_TCP_DATA % 256;
mE_TCP_SOCKET[num].TcpHeadUint8[24] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[25] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[26] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[27] = 0x01;
// 添加TCP伪报头
// Reserve
mE_TCP_SOCKET[num].TcpDHeadUint8[0] = 0;
// NextProtocal
mE_TCP_SOCKET[num].TcpDHeadUint8[1] = 6;
// TotalLen
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 28;
// SourceIp
mE_TCP_SOCKET[num].TcpDHeadUint8[4] = mE_TCP_SOCKET[num].My_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[5] = mE_TCP_SOCKET[num].My_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[6] = mE_TCP_SOCKET[num].My_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[7] = mE_TCP_SOCKET[num].My_Ip[3];
// DestIp
mE_TCP_SOCKET[num].TcpDHeadUint8[8] = mE_TCP_SOCKET[num].Dest_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[9] = mE_TCP_SOCKET[num].Dest_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[10] = mE_TCP_SOCKET[num].Dest_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[11] = mE_TCP_SOCKET[num].Dest_Ip[3];
// 计算校验码
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,40);
// TCP报头校验码
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
// 打数据包
TxdData.STPTR = NULL;
TxdData.LENGTH = 28;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
// 发送数据
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
}
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_SYN_REC(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 服务器发送完SYN-ACK,即可进入该状态,可接收ACK或RST-ACK或SYN-ACK
输入参数:
输出参数: 0: 对方同步ACK信号
2: 对方不接受SYN-ACK
3: 对方SYN
4: 无任何操作
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: 收到对方的ACK数据或RST-ACK或SYN-ACK
*****************************************************************************************/
uint8 mE_TCP_SYN_REC(uint8 num)
{
struct _pkst TxdData;
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_ACK) // 这是3次握手确认,表明连接建立
{
if(mE_TCP_BUFFER.Tcp_Data.SeqNum == (mE_TCP_SOCKET[num].RecFutureSeq))
if(mE_TCP_BUFFER.Tcp_Data.AckNum == (mE_TCP_SOCKET[num].RecFutureAck))
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_ESTABLISHED; // 建立连接状态
mE_TCP_SOCKET[num].Timer = 0x00; // 心跳
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq; // 下帧的接收确认
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP接收ACK信号,连接成功",1);
#endif
if((mE_TCP_SOCKET[num].StaSem & mE_TCP_WAIT_SEMCONN) == mE_TCP_WAIT_SEMCONN)
OSSemPost(TCP_SEM_CONN_SUCESS[num]);
return 0;
}
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SYN) == mE_TCP_SYN) // 收到同步信号
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n 收到同步信号,复位对方",1);
#endif
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_HEAD_HANDLE(num ,0x5000 + mE_TCP_RST + mE_TCP_ACK);
// TCP伪报头
// TotalLen
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 20;
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,32);
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
TxdData.STPTR = NULL;
TxdData.LENGTH = 20;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
// 发送数据
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
mE_DELETE_SOCKET(num);
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_RST) == mE_TCP_RST) // 处理RESET,对方不接受请求
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n 处理RESET,对方不接受请求",1);
#endif
mE_DELETE_SOCKET(num);
return 2;
}
return 3;
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_SYN_SENT(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 对发送同步信号后接收到的数据(SYN-ACK)进行处理
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint8 mE_TCP_SYN_SENT(uint8 num)
{
static uint32 initalseq = 25632451;
struct _pkst TxdData;
// 收到对方的SYN-ACK
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == (mE_TCP_SYN + mE_TCP_ACK))
{
if(mE_TCP_BUFFER.Tcp_Data.AckNum == mE_TCP_SOCKET[num].RecFutureAck) // 应答号配匹
{
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 默认为560
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
if(mE_TCP_BUFFER.Tcp_Data.Offset > 20)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
mE_TCP_HEAD_HANDLE(num ,0x5000 + mE_TCP_ACK); // 发送应答信号
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 20;
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,32);
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
TxdData.STPTR = NULL;
TxdData.LENGTH = 20;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
mE_TCP_SOCKET[num].State = mE_TCP_STATE_ESTABLISHED; // 连接成功
mE_TCP_SOCKET[num].Timer = 0x00; // 心跳
// 等待连接信息
if((mE_TCP_SOCKET[num].StaSem&mE_TCP_WAIT_SEMCONN) == mE_TCP_WAIT_SEMCONN)
{
OSSemPost(TCP_SEM_CONN_SUCESS[num]);
}
return 0;
}
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_SYN) // 只收到SYN信号
{
// 记录数据
mE_TCP_SOCKET[num].Dest_Port = mE_TCP_BUFFER.Tcp_Data.SourcePort; // 对方端口
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧顺序号
mE_TCP_SOCKET[num].RecPassAck = 0; // 对方此帧应答号
mE_TCP_SOCKET[num].SenPassSeq = initalseq; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq+1; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Snd_Window = mE_MAX_TCP_WINDOW; // 本地的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 对方接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].My_Max_Seg_Size = mE_MAX_TCP_DATA; // 本地接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
mE_TCP_SOCKET[num].State = mE_TCP_STATE_SYN_RCVD; // TCP_STATE_SYN_RCVD;
if(mE_TCP_BUFFER.Tcp_Data.Offset > 50)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
// 向对方发送SYN-ACK报
// 添加TCP头选项
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
版权所有:
版本号: 1.0.1
生成日期: 2005.1.1
文件名: mE_TCP.C
作者: 影舞者
功能说明: TCP层协议
其它说明:
所属文件关系: 本文件为工程规约代码文件
修改记录:
记录1:
修改者:
修改日期:
修改内容:
修改原因:
*****************************************************************************************/
#define mE_TCP_GLOBALS // 定义全局变量
#include "mE_TCPIP.H" // 以太网文件
#if mE_TCP_FUNC_ENABLE // TCP功能定义
/*****************************************************************************************
函数名称: uint16 mE_TCP_CREATE_HEAD_CRC(uint8 *check,uint16 length)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 计算校验和
输入参数: uint8 *check: 被校验数据起始地址
输出参数: uint16 length: 被校验数据长度,单位字
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP协议层
*****************************************************************************************/
uint16 mE_TCP_CREATE_HEAD_CRC(uint8 *check,uint16 length)
{
uint32 sum = 0, i;
for (i=0;i<(length)/2;i++) // 16位计算
{
sum = sum + ((uint32)check[2*i]<<8)+(uint32)check[2*i+1];
}
if(length&0x0001) // 长度为奇数个时,要进行该操作
{
sum = sum + ((uint32)check[2*i]<<8);
}
sum = (sum&0xffff)+((sum>>16)&0xffff); // 高16位和低16位相加
if(sum & 0xffff0000) // 表示有进位
{
sum++;
}
return ((uint16)(~((sum)&0xffff))); // 数据取反
}
/*****************************************************************************************
函数名称: uint16 mE_TCP_CHECKSUM1(uint8 num,uint16 length)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 计算校验和
输入参数: uint8 num: 被校验数据起始地址
uint16 length: 被校验数据长度,单位字
输出参数: ~((sum)&0xffff))
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint16 mE_TCP_CHECKSUM1(uint8 num,uint16 length)
{
uint16 i;
uint32 sum = 0;
for (i=0;i<6;i++)
{
sum = sum + ((uint32)mE_TCP_SOCKET[num].TcpDHeadUint8[2*i]<<8) + (uint32)mE_TCP_SOCKET[num].TcpDHeadUint8[2*i+1];
}
length = length-12;
i = 0;
while(i<(length/2))
{
sum = sum + ((uint32)mE_TCP_SOCKET[num].TcpHeadUint8[2*i]<<8) + (uint32)mE_TCP_SOCKET[num].TcpHeadUint8[2*i+1];
i++;
}
if(length&0x0001) // 长度为奇数个时,要进行该操作
{
sum = sum + (uint32)(mE_TCP_SOCKET[num].TcpHeadUint8[2*i])*256;
}
sum = (sum&0x0000ffff) + ((sum>>16)&0x0000ffff); // 高16位和低16位相加
if(sum & 0xffff0000)
{ // 表示有进位
sum++;
if(sum & 0xffff0000)
{ // 表示有进位
sum++;
}
}
return ( (uint16)(~((sum)&0xffff)) ); // 注意取反
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_INITIALIZE(void)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 初始化TCP协议
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint8 mE_TCP_INITIALIZE(void)
{
uint8 i;
for(i=0;i<mE_MAX_TCP_LINKS;i++)
{
mE_TCP_SOCKET[i].State = mE_TCP_STATE_CLOSED;
mE_TCP_SOCKET[i].StaSem = 0;
TCP_SEM_SEND_SUCESS[i] = OSSemCreate(0);
TCP_SEM_CONN_SUCESS[i] = OSSemCreate(0);
TCP_SEM_DISC_SUCESS[i] = OSSemCreate(0);
}
mE_TCP_BUFFER.Tcp_Head.Reserve = 0;
mE_TCP_BUFFER.Tcp_Head.NextProtocal = 6;
return 0;
}
/*****************************************************************************************
函数名称: void mE_DELETE_SOCKET(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 如果是非监听状态,则关闭
如果是监听状态,则恢复起始状态
输入参数: uint8 num: 索引值
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议,存在BUG
*****************************************************************************************/
void mE_DELETE_SOCKET(uint8 num)
{
uint16 i;
OS_ENTER_CRITICAL();
if((mE_TCP_SOCKET[num].StaSem&mE_TCP_FOR_LISTEN) == mE_TCP_FOR_LISTEN)
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_LISTEN;
mE_TCP_SOCKET[num].StaSem = mE_TCP_FOR_LISTEN|mE_TCP_WAIT_SEMCONN;
}
else
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_CLOSED;
mE_TCP_SOCKET[num].StaSem = 0;
}
do
{
i = OSSemAccept(TCP_SEM_CONN_SUCESS[num]);
}while(i != 0);
do
{
i = OSSemAccept(TCP_SEM_SEND_SUCESS[num]);
}while(i != 0);
do
{
i = OSSemAccept(TCP_SEM_DISC_SUCESS[num]);
}while(i != 0);
OS_EXIT_CRITICAL();
}
/*****************************************************************************************
函数名称: void mE_TCP_HEAD_HANDLE(uint8 num ,uint16 Tcp_headlength_Control)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 填充TCP报文头及TCP伪报头数据
输入参数: uint8 num : mE_TCP_SOCKET索引号
uint16 Tcp_headlength_Control: 帧头长度、标志
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
void mE_TCP_HEAD_HANDLE(uint8 num ,uint16 Tcp_headlength_Control)
{
// TCP报文头
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
// AckNum;
mE_TCP_SOCKET[num].TcpHeadUint8[8] = (mE_TCP_SOCKET[num].SenPassAck&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[9] = (mE_TCP_SOCKET[num].SenPassAck&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[10] = (mE_TCP_SOCKET[num].SenPassAck&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[11] = (mE_TCP_SOCKET[num].SenPassAck&0x000000ff);
// Offset;
mE_TCP_SOCKET[num].TcpHeadUint8[12] = (Tcp_headlength_Control&0xff00)>>8;
// Control;
mE_TCP_SOCKET[num].TcpHeadUint8[13] = Tcp_headlength_Control&0x00ff;
// Window;
mE_TCP_SOCKET[num].TcpHeadUint8[14] = (mE_TCP_SOCKET[num].Snd_Window&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[15] = mE_TCP_SOCKET[num].Snd_Window&0x00ff;
// Crc;
mE_TCP_SOCKET[num].TcpHeadUint8[16] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = 0;
// Urg;
mE_TCP_SOCKET[num].TcpHeadUint8[18] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[19] = 0;
// 添加TCP伪报头
// Reserve
mE_TCP_SOCKET[num].TcpDHeadUint8[0] = 0;
// NextProtocal
mE_TCP_SOCKET[num].TcpDHeadUint8[1] = 6;
// SourceIp
mE_TCP_SOCKET[num].TcpDHeadUint8[4] = mE_TCP_SOCKET[num].My_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[5] = mE_TCP_SOCKET[num].My_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[6] = mE_TCP_SOCKET[num].My_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[7] = mE_TCP_SOCKET[num].My_Ip[3];
// DestIp
mE_TCP_SOCKET[num].TcpDHeadUint8[8] = mE_TCP_SOCKET[num].Dest_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[9] = mE_TCP_SOCKET[num].Dest_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[10] = mE_TCP_SOCKET[num].Dest_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[11] = mE_TCP_SOCKET[num].Dest_Ip[3];
}
/*****************************************************************************************
函数名称: void mE_TCP_LISTEN(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 收到对方的SYN信息,进入监听处理,返回SYN-ACK
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: mE_TCP_BUFFER.Tcp_Data里16位变量的格式已全部转换完毕
*****************************************************************************************/
void mE_TCP_LISTEN(uint8 num)
{
static uint32 initalseq = 260132451;
struct _pkst TxdData;
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_SYN) // 是同步帧
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP接收SYN同步信号",1);
#endif
// 转换状态,记录数据
mE_TCP_SOCKET[num].State = mE_TCP_STATE_SYN_RCVD; // TCP_STATE_SYN_RCVD
mE_TCP_SOCKET[num].Dest_Port = mE_TCP_BUFFER.Tcp_Data.SourcePort; // 对方端口
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧顺序号
mE_TCP_SOCKET[num].RecPassAck = 0; // 对方此帧应答号
mE_TCP_SOCKET[num].SenPassSeq = initalseq; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq+1; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Snd_Window = mE_MAX_TCP_WINDOW; // 本地的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 对方接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].My_Max_Seg_Size = mE_MAX_TCP_DATA; // 本地接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
mE_TCP_SOCKET[num].TcpDataQWrPtr = 0; // 数据的长度
mE_TCP_SOCKET[num].TcpDataQRdPtr = 0;
// 获取最大的传输段
if(mE_TCP_BUFFER.Tcp_Data.Offset > 50) // 报头大于20字节
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP发送SYN-ACK信号",1);
mE_DEBUG_STRING("\n 发送序列号: ",1);
mE_DEBUG_DEC(mE_TCP_SOCKET[num].SenPassSeq,1);
mE_DEBUG_STRING("\n 发送确认号: ",1);
mE_DEBUG_DEC(mE_TCP_SOCKET[num].SenPassAck,1);
#endif
// 向对方发送SYN-ACK报
// 添加TCP头选项
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
// AckNum;
mE_TCP_SOCKET[num].TcpHeadUint8[8] = (mE_TCP_SOCKET[num].SenPassAck&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[9] = (mE_TCP_SOCKET[num].SenPassAck&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[10] = (mE_TCP_SOCKET[num].SenPassAck&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[11] = (mE_TCP_SOCKET[num].SenPassAck&0x000000ff);
// Offset;
mE_TCP_SOCKET[num].TcpHeadUint8[12] = 0x70;
// Control;
mE_TCP_SOCKET[num].TcpHeadUint8[13] = mE_TCP_SYN|mE_TCP_ACK;
// Window;
mE_TCP_SOCKET[num].TcpHeadUint8[14] = (mE_TCP_SOCKET[num].Snd_Window&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[15] = mE_TCP_SOCKET[num].Snd_Window&0x00ff;
// Crc;
mE_TCP_SOCKET[num].TcpHeadUint8[16] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = 0;
// Urg;
mE_TCP_SOCKET[num].TcpHeadUint8[18] = 0;
mE_TCP_SOCKET[num].TcpHeadUint8[19] = 0;
// 选项和填充
mE_TCP_SOCKET[num].TcpHeadUint8[20] = 0x02;
mE_TCP_SOCKET[num].TcpHeadUint8[21] = 0x04;
mE_TCP_SOCKET[num].TcpHeadUint8[22] = mE_MAX_TCP_DATA / 256;
mE_TCP_SOCKET[num].TcpHeadUint8[23] = mE_MAX_TCP_DATA % 256;
mE_TCP_SOCKET[num].TcpHeadUint8[24] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[25] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[26] = 0x01;
mE_TCP_SOCKET[num].TcpHeadUint8[27] = 0x01;
// 添加TCP伪报头
// Reserve
mE_TCP_SOCKET[num].TcpDHeadUint8[0] = 0;
// NextProtocal
mE_TCP_SOCKET[num].TcpDHeadUint8[1] = 6;
// TotalLen
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 28;
// SourceIp
mE_TCP_SOCKET[num].TcpDHeadUint8[4] = mE_TCP_SOCKET[num].My_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[5] = mE_TCP_SOCKET[num].My_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[6] = mE_TCP_SOCKET[num].My_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[7] = mE_TCP_SOCKET[num].My_Ip[3];
// DestIp
mE_TCP_SOCKET[num].TcpDHeadUint8[8] = mE_TCP_SOCKET[num].Dest_Ip[0];
mE_TCP_SOCKET[num].TcpDHeadUint8[9] = mE_TCP_SOCKET[num].Dest_Ip[1];
mE_TCP_SOCKET[num].TcpDHeadUint8[10] = mE_TCP_SOCKET[num].Dest_Ip[2];
mE_TCP_SOCKET[num].TcpDHeadUint8[11] = mE_TCP_SOCKET[num].Dest_Ip[3];
// 计算校验码
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,40);
// TCP报头校验码
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
// 打数据包
TxdData.STPTR = NULL;
TxdData.LENGTH = 28;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
// 发送数据
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
}
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_SYN_REC(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 服务器发送完SYN-ACK,即可进入该状态,可接收ACK或RST-ACK或SYN-ACK
输入参数:
输出参数: 0: 对方同步ACK信号
2: 对方不接受SYN-ACK
3: 对方SYN
4: 无任何操作
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: 收到对方的ACK数据或RST-ACK或SYN-ACK
*****************************************************************************************/
uint8 mE_TCP_SYN_REC(uint8 num)
{
struct _pkst TxdData;
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_ACK) // 这是3次握手确认,表明连接建立
{
if(mE_TCP_BUFFER.Tcp_Data.SeqNum == (mE_TCP_SOCKET[num].RecFutureSeq))
if(mE_TCP_BUFFER.Tcp_Data.AckNum == (mE_TCP_SOCKET[num].RecFutureAck))
{
mE_TCP_SOCKET[num].State = mE_TCP_STATE_ESTABLISHED; // 建立连接状态
mE_TCP_SOCKET[num].Timer = 0x00; // 心跳
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq; // 下帧的接收确认
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n TCP接收ACK信号,连接成功",1);
#endif
if((mE_TCP_SOCKET[num].StaSem & mE_TCP_WAIT_SEMCONN) == mE_TCP_WAIT_SEMCONN)
OSSemPost(TCP_SEM_CONN_SUCESS[num]);
return 0;
}
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SYN) == mE_TCP_SYN) // 收到同步信号
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n 收到同步信号,复位对方",1);
#endif
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_HEAD_HANDLE(num ,0x5000 + mE_TCP_RST + mE_TCP_ACK);
// TCP伪报头
// TotalLen
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 20;
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,32);
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
TxdData.STPTR = NULL;
TxdData.LENGTH = 20;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
// 发送数据
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
mE_DELETE_SOCKET(num);
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_RST) == mE_TCP_RST) // 处理RESET,对方不接受请求
{
#if (mE_TCP_DEBUG_ENABLE == 1)
mE_DEBUG_STRING("\n 处理RESET,对方不接受请求",1);
#endif
mE_DELETE_SOCKET(num);
return 2;
}
return 3;
}
/*****************************************************************************************
函数名称: uint8 mE_TCP_SYN_SENT(uint8 num)
版本号: 1.0.1
生成日期: 2005.1.1
作者: 影舞者
功能说明: 对发送同步信号后接收到的数据(SYN-ACK)进行处理
输入参数:
输出参数:
函数扇出清单:
函数扇入清单:
用到的公共资源:
其它说明: TCP层协议
*****************************************************************************************/
uint8 mE_TCP_SYN_SENT(uint8 num)
{
static uint32 initalseq = 25632451;
struct _pkst TxdData;
// 收到对方的SYN-ACK
if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == (mE_TCP_SYN + mE_TCP_ACK))
{
if(mE_TCP_BUFFER.Tcp_Data.AckNum == mE_TCP_SOCKET[num].RecFutureAck) // 应答号配匹
{
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧序列号
mE_TCP_SOCKET[num].RecPassAck = mE_TCP_BUFFER.Tcp_Data.AckNum; // 对方此帧确认号
mE_TCP_SOCKET[num].SenPassSeq = mE_TCP_SOCKET[num].RecPassAck; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 默认为560
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
if(mE_TCP_BUFFER.Tcp_Data.Offset > 20)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
mE_TCP_HEAD_HANDLE(num ,0x5000 + mE_TCP_ACK); // 发送应答信号
mE_TCP_SOCKET[num].TcpDHeadUint8[2] = 0;
mE_TCP_SOCKET[num].TcpDHeadUint8[3] = 20;
mE_TCP_BUFFER.Tcp_Data.Crc = mE_TCP_CHECKSUM1(num,32);
mE_TCP_SOCKET[num].TcpHeadUint8[16] = (mE_TCP_BUFFER.Tcp_Data.Crc&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[17] = mE_TCP_BUFFER.Tcp_Data.Crc&0x00ff;
TxdData.STPTR = NULL;
TxdData.LENGTH = 20;
TxdData.DAPTR = mE_TCP_SOCKET[num].TcpHeadUint8;
mE_IP_SEND_FRAME(&TxdData,mE_TCP_SOCKET[num].Dest_Ip,mE_TCP_SOCKET[num].My_Ip,6);
mE_TCP_SOCKET[num].State = mE_TCP_STATE_ESTABLISHED; // 连接成功
mE_TCP_SOCKET[num].Timer = 0x00; // 心跳
// 等待连接信息
if((mE_TCP_SOCKET[num].StaSem&mE_TCP_WAIT_SEMCONN) == mE_TCP_WAIT_SEMCONN)
{
OSSemPost(TCP_SEM_CONN_SUCESS[num]);
}
return 0;
}
}
else if((mE_TCP_BUFFER.Tcp_Data.Control&mE_TCP_SIG) == mE_TCP_SYN) // 只收到SYN信号
{
// 记录数据
mE_TCP_SOCKET[num].Dest_Port = mE_TCP_BUFFER.Tcp_Data.SourcePort; // 对方端口
mE_TCP_SOCKET[num].RecPassSeq = mE_TCP_BUFFER.Tcp_Data.SeqNum; // 对方此帧顺序号
mE_TCP_SOCKET[num].RecPassAck = 0; // 对方此帧应答号
mE_TCP_SOCKET[num].SenPassSeq = initalseq; // 本地此帧顺序号
mE_TCP_SOCKET[num].SenPassAck = mE_TCP_SOCKET[num].RecPassSeq+1; // 本地此帧应答号
mE_TCP_SOCKET[num].RecFutureSeq = mE_TCP_SOCKET[num].SenPassAck; // 下帧的接收确认
mE_TCP_SOCKET[num].RecFutureAck = mE_TCP_SOCKET[num].SenPassSeq+1; // 下帧的接收确认
mE_TCP_SOCKET[num].Rcv_Window = mE_TCP_BUFFER.Tcp_Data.Window; // 对方的WINDOW大小
mE_TCP_SOCKET[num].Snd_Window = mE_MAX_TCP_WINDOW; // 本地的WINDOW大小
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_MAX_TCP_DATA; // 对方接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].My_Max_Seg_Size = mE_MAX_TCP_DATA; // 本地接受最大数据包默认为mE_MAX_TCP_DATA
mE_TCP_SOCKET[num].ResendState = 0; // 超时发送状态,未用
mE_TCP_SOCKET[num].ResendTime = 0; // 超时时间,未用
mE_TCP_SOCKET[num].ResendLength = 0; // 超时发送长度,未用
mE_TCP_SOCKET[num].State = mE_TCP_STATE_SYN_RCVD; // TCP_STATE_SYN_RCVD;
if(mE_TCP_BUFFER.Tcp_Data.Offset > 50)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[0] == 0x02)
if(mE_TCP_BUFFER.Tcp_Data.TCPdata[1] == 0x04) // 0204为最大segment选项
{
mE_TCP_SOCKET[num].Dest_Max_Seg_Size = mE_TCP_BUFFER.Tcp_Data.TCPdata[2]*256 + mE_TCP_BUFFER.Tcp_Data.TCPdata[3];
}
// 向对方发送SYN-ACK报
// 添加TCP头选项
// SourcePort;
mE_TCP_SOCKET[num].TcpHeadUint8[0] = (mE_TCP_SOCKET[num].My_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[1] = mE_TCP_SOCKET[num].My_Port&0x00ff;
// DestPort;
mE_TCP_SOCKET[num].TcpHeadUint8[2] = (mE_TCP_SOCKET[num].Dest_Port&0xff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[3] = mE_TCP_SOCKET[num].Dest_Port&0x00ff;
// SeqNum;
mE_TCP_SOCKET[num].TcpHeadUint8[4] = (mE_TCP_SOCKET[num].SenPassSeq&0xff000000)>>24;
mE_TCP_SOCKET[num].TcpHeadUint8[5] = (mE_TCP_SOCKET[num].SenPassSeq&0x00ff0000)>>16;
mE_TCP_SOCKET[num].TcpHeadUint8[6] = (mE_TCP_SOCKET[num].SenPassSeq&0x0000ff00)>>8;
mE_TCP_SOCKET[num].TcpHeadUint8[7] = (mE_TCP_SOCKET[num].SenPassSeq&0x000000ff);
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |