赞
踩
UDP是无连接、不可靠、面向数据报的协议。第一步,了解报文格式,毕竟是通信协议,我们需要了解双方交互的数据在网络中的存在形式;第二步,了解UDP为什么不可靠;第三步,了解什么是面向数据报。
目录
长度:UDP首部 + UDP数据的总长度。接收方在向上交付之前,需要去除UDP首部,将剩余的UDP数据报交付给上层,因为UDP首部是固定长度的 8 个字节(64bit),所以要去除UDP首部并不是难事。
源端口号:当前报文是来自发送方的哪个应用程序。
目的端口号:当前报文要发给接收方主机的哪个应用程序。有了目的端口号,对方传输层在向上交付的时候就知道要交付给上层哪个应用程序。
答案是位段。位段是结构体的一种功能,能够准确分配位段成员所占内存大小。UDP协议规定端口号的长度是 16 bit,所以在定义端口号的时候,我们总是使用 uint16_t 来作为端口号的数据类型。
- struct udp{
- uint16_t src_port: 16;
- uint16_t dst_port: 16;
- uint16_t len: 16;
- uint16_t check: 16;
- }
主要原因是UDP没有确认机制。主机A给主机B发送消息,主机A并不知道自己的消息是否成功发送给对方,主机B即便是收到了数据,也不会回复一声“收到”;主机B如果因为网络故障没有收到数据,主机B不会返回任何错误信息。
这就造成了每次通信都是双方主机 各发各的,消息我发了,收没收到,就事不关己高高挂起。
别人给我发的数据,要么全收,要么不收;不会拆分,不会合并。也就是说,主机A 给 主机B 发送了一个总长度为100 字节的数据包,主机B就必须一次性地把 这100个字节全部接收,不可以分10次循环调用接收,如果无法一次接收就会直接将这个UDP报文丢弃。
那么什么时候需要手动拼接呢??UDP协议有个UDP长度是16位,也就是说,一个UDP能传输数据的最大长度是64K(包含首部长度),如果我们发送的数据超过64K,那么我们就要在发送的时候手动分包,接收的时候手动拼接。
在说明UDP缓冲区之前,先抛出两个问题。问题一:发送方应用层下发数据以后,数据交给了谁?问题二:接收方传输层收到数据以后,数据存放在哪?
应用层下发数据,本质上就是将数据临时存放在“缓冲区”,因为什么时候发、发多少字节,不是应用层决定的,而是传输层决定的。应用层只负责下发数据,决策工作交由传输层,这就实现了上层应用和网络传输的解耦。
实际上TCP有发送缓冲区,但是UDP没有发送缓冲区,应用层调用接口函数sendto发送UDP数据的时候,其实是直接将数据拷贝给内核,内核再将数据传给网络层协议进行后 续的传输动作
TCP和UDP都有接收缓冲区,UDP会将从网络接收的数据存放在缓冲区里,上层调用recvfrom接口函数时再从缓冲区拷贝。UDP的接收缓冲区不能保证收到的顺序和发送的顺序一致,因为UDP没有确认机制,即便是接收方的缓冲区满了,后续到达的UDP数据报会被丢弃,也不会通知对方。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。