📄 tcpip.h
字号:
// TCP标识 TcpHdr_Stru.HdrLen 代表TCP头长度,以32bit(4 byte)为单位
#define cTCP_HDR_NOOPT 0x05 // TCP头无操作选项
#define cTCP_HDR_OPT 0x07 // TCP头有操作选项,操作选项长度4 word 或8 byte
// TCP标识 TcpHdr_Stru.Flags
#define cTCP_FIN 0x01
#define cTCP_SYN 0x02
#define cTCP_RST 0x04
#define cTCP_PSH 0x08
#define cTCP_ACK 0x10
#define cTCP_URG 0x20
UINT16 WndSize; // 窗口大小,表明接还能容纳的TCP数据(最大0xFFFF)
#define cTCP_WS 1460 // 定义本地窗口,必须满足条件:cTCP_MSS <= cTCP_MSS <= 0xFFFF
UINT16 TcpChkSum;
UINT16 UrgPoint; // 紧急指针
// UINT16 OptData[2];
// 最长TCP报文大小(头选项之一):字节(最大1460)
#define cTCP_MSS 1460 // 定义本地最大TCP报文长度
}TcpHdr_Stru;
// TCP 本地初始32位序号
extern volatile UINT16 guwISN[2];
// TCP头的常数指针。
#define cpTcpHdrBuf ((UINT16 *)&guwEthBuf[cEthHdrLen + cIpHdrLen]) // 指向Word的buffer
#define cptTcpHdrBuf ((TcpHdr_Stru *)&guwEthBuf[cEthHdrLen + cIpHdrLen]) // 指向结构
// TCP数据段指针
#define cpTcpData ((UINT16 *)&guwEthBuf[cEthHdrLen + cIpHdrLen + cTcpHdrLen]) // 指向Word的buffer
//---------------------------------------------------------------------------------
// ARP表结构
typedef struct{
UINT16 IpAddr[2];
UINT16 EthAddr[3];
UINT16 Time2; // 刷新时刻,2Hz的计数
// ARP表记录的最大老化清除时间:20分钟(4.4BSD-Lite 默认)。
#define cArpMaxAge 20*60
}ArpEntries_Stru;
// 最大ARP表记录数
#define cArpTabSize 16
// 分配ARP链表的内存
extern ArpEntries_Stru gstArpTab[cArpTabSize];
// ARP表记录的地址
#define cptArpTabStart ((ArpEntries_Stru *)&gstArpTab[0]) // 指向结构,开始地址指针
#define cptArpTabEnd ((ArpEntries_Stru *)&gstArpTab[cArpTabSize]) // 指向结构,结束地址指针
//---------------------------------------------------------------------------------
// TCP事务联接状态记录结构
typedef struct{
UINT16 TcpStateFlags; // TCP状态和标识
// TCP 事务状态标识 Conn_Stru->TcpStateFlags
#define cTCP_CLOSED 0x00
#define cTCP_SYN_RCVD 0x01
#define cTCP_SYN_SENT 0x02
#define cTCP_ESTABLISHED 0x03
#define cTCP_FIN_WAIT_1 0x04
#define cTCP_FIN_WAIT_2 0x05
#define cTCP_CLOSING 0x06
#define cTCP_TIME_WAIT 0x07
#define cTCP_CLOSE_WAIT 0x08
#define cTCP_LAST_ACK 0x09
#define cTCP_TS_MASK 0x0f
#define cTCP_OUTSTANDING 0x10
#define cTCP_STOPPED 0x20
UINT16 LocalPort; // 本地端口
UINT16 RemotePort; // 远端端口
UINT16 RemoteIpAddr[2]; // 远端IP
UINT16 RcvNum[2]; // 下次接收包的远端32位Seq序号
UINT16 AckNum[2]; // 下次接收包的远端32位Ack序号
UINT16 SeqNum[2]; // 本地当前包32位Seq序号
UINT16 MaxSegSize; // 本连接事务使用的最长TCP报文大小,详见TCP头结构说明
UINT16 Timer; // 状态需要等待的时间
UINT16 NumRetran; // 重传次数
UINT16 PollTime; // 空闲时间计数
// 由于TCP事务轮询时间为1秒,所以300秒空闲就异常终止当前连接。(WIN2K用900秒)
#define cTCP_MAX_POLL 300
}Conn_Stru;
// TCP最大联接事务数。
#define cMaxConnetions 16
// 分配TCP最大联接事务链表内存
extern Conn_Stru gstConns[cMaxConnetions];
// TCP最大联接事务记录表首地址
#define cptConnsStart ((Conn_Stru *)&gstConns[0]) // 指向结构
// TCP最大联接事务记录表结束地址
#define cptConnsEnd ((Conn_Stru *)&gstConns[cMaxConnetions]) // 指向结构
// 用于RTT估计器的重传指数退避时间,公式: T = cTCP_RTO * 2^n (n表示第几次重传)
#define cTCP_RTO 3
// TCP超时关闭联接的时间,即在TIME_WAIT状态的联接保持时间
#define cTCP_TIME_WAIT_2MSL 120 // 120 秒(因为TCP事务1秒轮询1次)
// TCP最大重传次数
#define cTCP_MAXRTX 3
// 本地TCP端口范围
#define cLocalPortStart 4096 // 开始:0x1000
#define cLocalPortEnd 28672 // 结束:0x7000
// TCP最大侦听端口数。除非作为Web服务器,否则通常为1
#define cMaxListenPorts 8 // 本应用允许侦听端口
// 当前TCP事务联接指针
extern Conn_Stru *gptConn;
// 分配TCP侦听端口号链表内存
extern UINT16 guwListenPorts[cMaxListenPorts];
//---------------------------------------------------------------------------------
// 其它定义
// 正在处理包的字节长度(byte)。这个值随处理正在处理的协议层的不同而改变!
extern volatile UINT16 guwEthLen;
// TCP/IP协议栈和应用程序间通讯的变量
extern volatile UINT16 guwFlags;
// 协议层通过guwFlags与应用层的联系常数定义
#define cTCP_ACKDATA 0x01 // 上次发的数据已经被确认,通知应用程序可以发新的数据
#define cTCP_NEWDATA 0x02 // 远端发给本地数据包,协议层需要ACK回应
#define cTCP_REXMIT 0x04 // 通知应用程序重发上次的数据包
#define cTCP_POLL 0x08 // 如果应用程序等待发数据,就给它一个标识POLL
#define cTCP_CLOSE 0x10 // 远端已经关闭联接,或应用程序要关闭联接
#define cTCP_ABORT 0x20 // 远端要放弃联接,或应用程序要放弃联接
#define cTCP_CONNECTED 0x40 // 联接成功建立
#define cTCP_TIMEDOUT 0x80 // 超过重传次数,放弃联接
// cTCP_DATA:msip_Process()的入口参数,表示需要处理已经在guwEthBuf缓冲区的包。
// cTCP_TIMER:msip_Process()的入口参数,表示需要做周期性的TCP事务处理。
#define cTCP_DATA 1
#define cTCP_TIMER 2
//---------------------------------------------------------------------------------
// 以太收发功能
// ether_Send(): 发送以太包宏定义,兼容性定义
#define ether_Send() RTL8019AS_TX(guwEthLen, cpEthHdrBuf)
// ether_Receive(): 接收以太包宏定义,兼容性定义
#define ether_Receive() RTL8019AS_RX(cpEthHdrBuf)
//---------------------------------------------------------------------------------
// ARP 功能过程
// msip_Arp_Timer():ARP表老化扫描,每8秒执行1次(BSD default 10 seconds)
// 超过20分钟(BSD default)未变化的,将被删除!
extern void msip_Arp_Time(void);
// msip_Arp_Update():ARP表更新过程。
// uwIpAddr:IP地址
// uwEthAddr:物理地址
// 返回更新的ARP表的地址。如果地址在表外,说明更新失败。
extern ArpEntries_Stru *msip_Arp_Update(UINT16 *uwIpAddr, UINT16 *uwEthAddr);
// msip_Arp_In():如果检测到ARP包输入就执行。
// 如果远端ARP请求,过程发送ARP回应。
// 如果远端ARP回应,过程更新ARP表。
extern void msip_Arp_In(void);
// msip_Arp_Out():将待发送的IP包封装以太头,并发送封装好的以太包
// pARPTAB:指向ARP表中远端IP和物理地址的影射表记录地址
// 如果pARP是空指针,原IP包将被破坏,并且用ARP请求包替代发送。
extern void msip_Arp_Out(ArpEntries_Stru *pARPTAB);
//---------------------------------------------------------------------------------
// TCP/IP 功能:
// msip_TcpChkSum():TCP/IP校验和过程。
extern UINT16 msip_TcpChkSum(void);
// msip_Process(): TCP/IP 全处理过程
// uwFlag:处理类型,见cTCP_DATA和cTCP_TIMER
// pConn:TCP事件指针
extern void msip_Process(UINT16 uwFlag);
// 系统接口类:
// msip_Init(): TCP/IP功能初始化,必须在其它TCP/IP处理前调用。包含ARP、被动侦听端口和TCP事务连接
extern void msip_Init(void);
// msip_Periodic(): TCP/IP事务周期轮询过程,1秒发生1次
extern void msip_Periodic(void);
// msip_Input(): 如果输入的是IP包,接执行改过程。
#define msip_Input() msip_Process(cTCP_DATA)
// msip_APPCALL(): 供用户写TCP应用代码的函数名。
#define userapp msip_APPCALL // 指向RS232应用
// 应用程序接口类:(应用层控制协议层状态变迁)
// msip_Listen(): TCP/IP被动侦听本地端口是否被占用!用于服务端
// uwPort:本地TCP端口
// 返回0:表示端口被用
// 返回1:表示建立成功
extern UINT16 msip_Listen(UINT16 uwPort);
// msip_Connect(): TCP/IP建立主动联接远端,用于客户端
// uwLocalPort:本地TCP端口
// puwRemoteIpAddr:远端IP地址
// uwRemotePort:远端TCP端口
// 返回0:表示建立失败
// 返回1:表示建立成功
#if TCP_ACTIVE_OPEN == 1
extern UINT16 msip_Connect(UINT16 uwLocalPort, UINT16 *puwRemoteIpAddr, UINT16 uwRemotePort);
#endif
// msip_Send():发送数据到当前的连接,保留的uIP定义,我们不用
#define msip_Send()
// msip_DataLen():当前TCP数据段的长度(Bytes),保留的uIP定义,我们不用
#define msip_DataLen() guwEthLen
// msip_Close(): 主动关闭当前连接,应用层通知协议层正常关闭当前连接(FIN)
#define msip_Close() (guwFlags = cTCP_CLOSE)
// msip_Abort():异常关闭当前连接,应用层通知协议层复位当前连接(RST)
#define msip_Abort() (guwFlags = cTCP_ABORT)
// msip_Stop(): 停止接收含TCP数据段的包,应用层通知协议层将窗口尺寸设置为0,期待远端暂停发送带数据的TCP包!
#define msip_Stop() (gptConn->TcpStateFlags |= cTCP_STOPPED)
// msip_Restart(): 重新开始当前的连接,应用层通知协议层重新开放窗口尺寸,以便允许远端发送带数据的TCP包!
#define msip_Restart() {guwFlags |= cTCP_NEWDATA; gptConn->TcpStateFlags &= ~cTCP_STOPPED;}
// 测试判断接口类:(应用层查询协议层状态)
// msip_connected():
// 服务或服务都有效,表明当前连接建立成功!状态只会出现一次!
// 在客户模式可以传TCP数据;服务模式最好不发送数据!
#define msip_Connected() (guwFlags & cTCP_CONNECTED)
// msip_Poll():
// 不论是服务或客户,都表明协议层处于连接空闲状态!标识由TCP事件轮询传回,在这个状态下可设置
// 空闲计数器记录空闲次数,达到一定时间就异常终止连接!如果这样做,就不能在这个状态发送数据!
// 允许发送数据的条件是:((guwEthLen > 0) || (guwFlags & cTCP_NEWDATA))
#define msip_Poll() (guwFlags & cTCP_POLL)
// msip_NewData():处于ESTABLELISH状态
//(guwEthLen > 0)协议层收到远端发出TCP数据包,并期待应用层处理:在这个状态下,允许只
// 发送无TCP数据的ACK确认(设置:guwEthLen = 0),或者发送带TCP数据的ACK确认(把要发送的
// TCP数据长度设置给guwEthLen)。
#define msip_NewData() (guwFlags & cTCP_NEWDATA)
// msip_Acked():处于ESTABLELISH状态
//(guwEthLen = 0)协议层收到远端发出ACK确认包。在这个状态下,允许发送带TCP数据的ACK
// 确认(把要发送的TCP数据长度设置给guwEthLen),或者不响应。
#define msip_Acked() (guwFlags & cTCP_ACKDATA)
// mip_Reset_Acked(): 清除确认后的标志,好象没有用?!(也许用于重传)
#define mip_Reset_Acked() (guwFlags &= ~cTCP_ACKDATA)
// msip_Rexmit(): 应用层上次的以发数据需要重传,标识由TCP事件轮询传回!应用层不允许更改guwEthLen的值!!!
#define msip_Rexmit() (guwFlags & cTCP_REXMIT)
// msip_Stopped(): 当前连接已经停止接收含TCP数据段的包,连接是正常的。
#define msip_Stopped() (gptConn->TcpStateFlags & cTCP_STOPPED)
// msip_Aborted(): 当前连接已经异常关闭,协议层发送RST复位包。
#define msip_Aborted() (guwFlags & cTCP_ABORT)
// msip_Closed(): 当前连接已经正常关闭,应用层发送FIN包
#define msip_Closed() (guwFlags & cTCP_CLOSE)
// msip_TimedOut(): 当前连接时间溢出,并且连接因时间溢出异常关闭,协议层发送RST复位包。
#define msip_TimedOut() (guwFlags & cTCP_TIMEDOUT)
// 附加接口类:-------------------------------------------------------------------
// msip_MSS(): 读 TCP/IP 的MSS,以决定将要发送的数据长度远端是否能接受。
#define msip_MSS() (gptConn->MaxSegSize)
//--------------------------------------------------------------------------------------
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -