文章目录
- UDP 协议
- 1. 面向数据报
- 2. UDP 协议端格式
- 3. UDP 的封装和解包
- 4. UDP 的缓冲区
UDP 协议
UDP传输的过程类似于寄信。
- 无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接。
- 不可靠:没有确认机制,没有重传机制;如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息。
- 面向数据报: 不能够灵活的控制读写数据的次数和数量。
1. 面向数据报
数据报是独立的一整个,应用层交给 UDP 多长的报文,UDP原样发送,既不会拆分,也不会合并。
例如:用 UDP 传输 100 个字节的数据:如果发送端调用一次 sendto,发送100个字节,那么接收端也必须调用对应的一次recvfrom,接收100字节。而不能循环调用10次recvfrom, 每次接收10个字节。
2. UDP 协议端格式
UPD 的协议报头长度是 固定的 8字节。
16位 UDP 长度,表示整个数据报(UDP 首部 + UDP 数据)的 最大长度,即 216 = 64kb。
如果校验和出错, 就会直接丢弃。
报头(协议)的本质其实就是:结构化数据(结构体、位段)
// 结构体实现
struct udp_header
{uint16_t src_port;uint16_t dst_port;uint16_t udp_len;uint16_t check;
};
// 位段实现
struct udp_header
{uint32_t src_port:16;uint32_t dst_port:16;//...
};
3. UDP 的封装和解包
🎯封装
- 应用层将信息拷贝给传输层,用
char* p
指针指向一个缓冲区,前面放 UDP 结构报头(固定 8 字节),后面放有效载荷,对报头内容的填充就可以写作:
((struct udp_header*)p)->src_port = xx;
((struct udp_header*)p)->dst_port = xx;
((struct udp_header*)p)->udp_len = xx;
((struct udp_header*)p)->check = xx;
🎯封装
- 应用层将信息拷贝给传输层,用
char* p
指针指向一个缓冲区,前面放 UDP 结构报头(固定 8 字节),后面放有效载荷,对报头内容的填充就可以写作:
((struct udp_header*)p)->src_port = xx;
((struct udp_header*)p)->dst_port = xx;
((struct udp_header*)p)->udp_len = xx;
((struct udp_header*)p)->check = xx;
4. UDP 的缓冲区
UDP 没有真正意义上的 发送缓冲区。调用 sendto 会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
UDP 具有接收缓冲区。但是这个接收缓冲区不能保证收到的 UDP 报的顺序和发送 UDP 报的顺序一致。如果缓冲区满了,再到达的UDP数据就会被丢弃。
UDP 的 socket 既能读,也能写, 这个概念叫做 全双工