目录
udp
报文格式
- 采用定长报头(8个字节)
端口号
传输层的上一层就是应用层了,每个服务都有自己的端口号,且和pid关联
使用目的端口号即可定位自己的上层,然后把有效载荷交给对应进程
udp长度
指整个报文的长度
- [udp长度-8]就是有效载荷长度
- 这个长度是16位的,按照这个长度,每个udp报文最大是64kb
如果要发送大于64kb的数据呢?
- 就需要自己在应用层将数据做切割,然后再发送
检验和
是为了检测传输数据是否有偏差
- 因为整个通信过程要经过很多设备,很有可能出现偏差
- 还记得吗,我们的传输层就是为了提供供端到端的数据传输服务,即使udp协议不保证可靠性,依然也会检测传输错误
- 当校验成功才会把有效载荷分离,并交付给上层
- 校验失败则直接丢弃,而不会通知重新发送 -- 这也就体现了udp协议不保证可靠性的特性
udp的特点
已经在之前的博客里介绍过了--传输层协议介绍(tcp,udp),可靠性和不可靠性_可靠传输服务和不可靠传输服务 udp tcp-CSDN博客
这里只是再拓展一些
面向数据报
每个报文都有明显的界限
- 对方发几次,自己就得收几次
就像寄信收信,寄邮件发邮件一样
- 它不像我们之前在网络计算器里使用的tcp协议一样,要对收到的数据进行检测
- 它要么没收到,要么收到完整的一份
缓冲区
tcp协议是发送缓冲区和接收缓冲区都有
而udp协议,没有真正的发送缓冲区
- 因为会直接给数据添加报头后就发送,他不需要发送缓冲区
有接收缓冲区
- 用于存放用户未来得及处理的报文
因为udp协议不保证可靠性
- 所以收到的报文顺序可能会和接收的顺序不一致
- 就像俩人约好去一个地方,其中一个先出发,但不一定就先到达
- 可能路上遇到点事啥的
- 总之,发送报文时可能会出现乱序 --> 本次发送并不可靠
- 但udp不管这么多,发了就行
还有,如果一方的接收缓冲区已经满了,但另一方还在发送
- 就会直接丢弃多余的报文
- 因为满的一方不会通知另一方不要再发送,满了之后直接丢弃多余报文
全双工
早在我们之前写网络聊天室时,就已经使用过udp协议
- udp的套接字既可以读,又可以写
- 所以属于全双工
- tcp也是如此
应用
通常用于需要快速传输数据但对数据可靠性要求不高的应用场景 -- 比如直播,视频等
清晰度
为什么可以动态调整清晰度?
- 视频的图像是从视频流里进行信息提取
- 像素密集就是高清的
- 不太密集的就糊一点
一旦出现丢包,可能视频就会卡顿/突然糊了
基于udp的应用层协议
其实,说的这些应用场景,其实都取决于应用层
- 应用层协议基于udp协议做出来的东西,需要udp协议满足它们的场景需要,这才有了udp的应用场景
- tcp协议同理
实现形式
引入
udp协议最终是要落在代码里的,而操作系统都是用c/c++编写的
- 要被进程使用一定是在内存里的,那就一定得有变量给它兜着
- 所以,它的实现形式就是结构体
- 就像在协议的概念+本质+作用+最终表现形式,网络问题(技术+应用+解决的协议+存在原因),主机的对称性-CSDN博客介绍的一样
介绍
添加协议报头就是填充结构体里的报头字段:
其他协议也是如此
如何管理报文
在传输过程中,一定会有多个报文在内核里存在
- 一台机器可以向多个主机发送请求,也就会有多个响应发回来
要不要管理呢?
要
- 于是就有了sk_buff 这个描述结构体,存放指向报文不同位置的指针
- 根据协议类型来决定指针类型
- 然后多个sk_buff连在一起,就形成了链表
那么:
- 管理报文数据,就是在管理链表元素
- 丢弃报文,就是删除链表结点