Appearance
传输协议
主要有两个, TCP和UDP
UDP
c
struct udp_hdr {
PACK_STRUCT_FIELD(u16_t src);
PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */
PACK_STRUCT_FIELD(u16_t len);
PACK_STRUCT_FIELD(u16_t chksum);
} PACK_STRUCT_STRUCT;
实际使用的时候应用层需要一个头部为54字节的pbuf, 可以兼容TCP协议, 之后根据使用的协议进行添加首部
实际连接的时候使用的控制块, 实际处理的时候会判断获取的UDP数据是不是和端口是一致的, 如果是的话使用回调函数进行处理
TCP
使用这一个协议的时候是不会进行IP分片的, 如果数据比较大, 只会在传输层进行分包
这一个协议栈里面定义了MSS, 为了提高性能, lwIP定义为1460
TCP协议中的MSS(Maximum Segment Size)指的是在TCP通信中,一个TCP报文段的最大有效载荷数据量,即TCP头部和TCP数据部分的最大长度。MSS是在TCP连接建立时由双方协商确定的,通常取决于网络设备和操作系统的配置。
以下是关于TCP协议的MSS的一些重要信息:
- 协商过程:
- 在TCP连接建立的握手阶段(三次握手),客户端和服务器会交换彼此支持的MSS值。
- 客户端会在SYN报文段的TCP选项中发送其MSS值给服务器。
- 服务器收到SYN报文段后,也会在发送SYN-ACK报文段时回复其MSS值给客户端。
- 客户端收到服务器的SYN-ACK后,最后发送一个ACK报文段确认连接建立,此时双方已确认并协商了MSS。
- 影响因素:
- MSS的大小可以受到网络设备(如防火墙)和操作系统配置的影响。
- 一般情况下,MSS的大小会被设备和操作系统限制为一定的值,通常是通过TCP栈的配置参数来调整。
- 默认值:
- 在大多数情况下,MSS的默认值是根据网络接口的最大传输单元(MTU,Maximum Transmission Unit)来确定的,减去TCP头部和IP头部的长度后留下的有效载荷大小。
- 在以太网上,MTU通常为1500字节,因此默认的MSS可能会设为1460字节(1500 - 40,TCP头部20字节,IP头部20字节)。
- 优化和调整:
- 在特定的网络环境下,可以通过调整操作系统的TCP参数或者中间设备的配置来优化MSS的大小,以提高TCP传输效率和减少报文段重组的需求。
- 应用:
- MSS的大小对TCP连接的性能有一定影响,过大的MSS可能导致分段重组的增加,而过小的MSS则可能导致报文段的浪费和TCP效率的下降。
- TCP/IP协议栈在发送数据时,会根据MSS值将数据分段,并在接收端重新组装成完整的数据流。
总之,MSS在TCP连接中起着重要的作用,它影响了数据传输的效率和网络吞吐量,因此在配置和优化网络性能时需要特别注意和理解MSS的设定和影响。
数据格式
TCP数据段
- 与UDP协议一样也有源端口号和目的端口号,通讯的双方由IP地址和端口号标识。
- 32位序号: 以一个随机数为起始, 每一次加上数据的长度
- 32位确认序号: 发送期望得到的数据的起始位置
- 4位首部长度和IP协议头类似,表示TCP协议头的长度,以4字节为单位,因此TCP协议头最长可以是4x15=60字节,如果没有选项字段,TCP协议头最短20字节。
- URG、ACK、PSH、RST、SYN、FIN是六个控制位
- ACK:确认序号有效
- RST:重置连接
- SYN:发起了一个新连接
- FIN:释放一个连接
- PSH: 当 PSH = 1 的时候,表示该报文段高优先级
- 16位窗口: 告诉对方本端的 TCP 接收缓冲区还能容纳多少字节的数据
- 16位检验和将TCP协议头和数据都计算在内。
- 紧急指针: 仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数。
- 各种选项
在实际实现的时候, 需要实现滑动窗口以及三次握手, 四次挥手
c
struct tcp_hdr {
PACK_STRUCT_FIELD(u16_t src);
PACK_STRUCT_FIELD(u16_t dest);
PACK_STRUCT_FIELD(u32_t seqno);
PACK_STRUCT_FIELD(u32_t ackno);
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);
PACK_STRUCT_FIELD(u16_t wnd);
PACK_STRUCT_FIELD(u16_t chksum);
PACK_STRUCT_FIELD(u16_t urgp);
} PACK_STRUCT_STRUCT;
c
enum tcp_state {
CLOSED = 0,
LISTEN = 1,
SYN_SENT = 2,
SYN_RCVD = 3,
ESTABLISHED = 4,
FIN_WAIT_1 = 5,
FIN_WAIT_2 = 6,
CLOSE_WAIT = 7,
CLOSING = 8,
LAST_ACK = 9,
TIME_WAIT = 10
};