Linux 传输层协议UDP
传输层
负责数据能够从发送端传输接收端.
再谈端⼝号
端⼝号(Port)标识了⼀个主机上进⾏通信的不同的应⽤程序;

在TCP/IP协议中,⽤"源IP","源端⼝号","⽬的IP","⽬的端⼝号","协议号"这样⼀个五元组来标识⼀个 通信(可以通过netstat-n查看);
端⼝号范围划分
• 0-1023:知名端⼝号,HTTP,FTP,SSH等这些⼴为使⽤的应⽤层协议,他们的端⼝号都是固定的.
• 1024-65535:操作系统动态分配的端⼝号.客⼾端程序的端⼝号,就是由操作系统从这个范围分配 的.
认识知名端⼝号
有些服务器是⾮常常⽤的,为了使⽤⽅便,⼈们约定⼀些常⽤的服务器,都是⽤以下这些固定的端⼝号: • ssh服务器,使⽤22端⼝
• ftp服务器,使⽤21端⼝
• telnet服务器,使⽤23端⼝
• http服务器,使⽤80端⼝
• https服务器,使⽤443
执⾏下⾯的命令,可以看到知名端⼝号
cat /etc/services
我们⾃⼰写⼀个程序使⽤端⼝号时,要避开这些知名端⼝号.
两个问题
1. ⼀个进程是否可以bind多个端⼝号?
可以。 一个进程能创建多个独立的 Socket,每个 Socket 分别调用bind()绑定不同的端口,就能实现单进程监听多个端口。
2. ⼀个端⼝号是否可以被多个进程bind?
默认不可以;特殊配置下可行。 默认系统会限制端口独占绑定,一个端口被进程绑定后,其他进程无法再绑定; 给 Socket 设置SO_REUSEADDR/SO_REUSEPORT套接字选项、满足对应约束后,多个进程可以绑定同一个端口。
UDP协议
UDP协议端格式

源端口:发送进程绑定的端口,用于回复。可为 0(表示不需要回复)。
目的端口:接收进程的端口,是 UDP 实现多路分用的唯一核心依据。
长度:整个 UDP 数据报的长度(头部+数据),最小为 8(即无数据)。
校验和:覆盖 UDP 头部、数据和从 IP 层提取的部分信息(伪首部),用于差错检测。在 IPv4 中可选(可全为 0 表示不校验),IPv6 中则强制计算。
UDP的特点
UDP传输的过程类似于寄信.
- 无连接:传输前无需建立连接(无三次握手),发完也无需释放连接,启动快、延迟低。
- 不可靠交付:不保证数据一定送达、不保证顺序、不做重传和拥塞控制,丢包不补救。
- 面向报文:对应用层的报文直接封装,不拆分、不合并,一次发送一个完整报文。
- 头部开销极小:固定 8 字节报头,远小于 TCP,传输额外成本低。
- 支持多模式通信:除了一对一,还支持广播、多播(一对多、多对多),适合直播、语音、实时游戏等场景
⾯向数据报
应⽤层交给UDP多⻓的报⽂,UDP原样发送,既不会拆分,也不会合并;
⽤UDP传输100个字节的数据:
• 如果发送端调⽤⼀次sendto,发送100个字节,那么接收端也必须调⽤对应的⼀次recvfrom,接收 100个字节;⽽不能循环调⽤10次recvfrom,每次接收10个字节;
UDP的缓冲区
与 TCP 那种“字节流缓存”不同,UDP 的缓冲区完全是另一套逻辑,直接体现了它无连接、不可靠的本质。

• UDP没有真正意义上的发送缓冲区.调⽤sendto会直接交给内核,由内核将数据传给⽹络层协议进 ⾏后续的传输动作;
• 那通过 SO_SNDBUF 设置的“发送缓冲区”是什么?它本质上是一个限制单套接字在“发送途中”占用内核内存总量的配额。
作用机制:当数据报提交给 IP 层到网卡硬件真正完成发送之间,会短暂占用内核内存(如排队在流量控制 qdisc 中)。如果应用发得过快,占用内存会持续增长。一旦“在途”内存总量超过该配额:
• 阻塞套接字:sendto 会阻塞,直到内存释放。
• 非阻塞套接字:立即返回 EAGAIN / EWOULDBLOCK 错误。
• 实质:它为无节制的 UDP 发送提供了一个本地的“背压”机制,防止一个进程耗尽所有内核内存。
• UDP具有接收缓冲区.但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序⼀ 致;如果缓冲区满了,再到达的UDP数据就会被丢弃;
UDP的socket既能读,也能写,这个概念叫做全双⼯.
总结
TCP有发送缓冲区是因为如果数据丢了要重传。只有收到数据已送达的信号才会清空发送缓冲区;
UDP是不可靠传输协议,数据丢了就丢了。没有重传这一概念,因此没有发送缓冲区。
为什么UDP要有接收缓冲区?
因为进行网络通信时,上层要做很多工作。因此OS要提供一个接收数据的能力,上层忙的时候,OS也能缓存一部分报文,如果接收缓冲区满了,再发送报文,则该报文会被丢弃,丢弃后UDP并不会关心。
报文的理解
报文=报头+有效数据载荷;
在OS内部,一定可能会同时存在大量报文。而OS就必须管理这些报文。
所以就有了sk_buff结构体——>内有4个重要指针:head,data,tail,end。
所谓的封装和解包,本质就是移动(+、-对应协议长度)data指针在缓冲区的指向;
UDP使⽤注意事项
我们注意到,UDP协议⾸部中有⼀个16位的最⼤⻓度.也就是说⼀个UDP能传输的数据最⼤⻓度是 64K(包含UDP⾸部).
然⽽64K在当今的互联⽹环境下,是⼀个⾮常⼩的数字.
如果我们需要传输的数据超过64K,就需要在应⽤层⼿动的分包,多次发送,并在接收端⼿动拼装;
基于UDP的应⽤层协议
• NFS:⽹络⽂件系统
• TFTP:简单⽂件传输协议
• DHCP:动态主机配置协议
• BOOTP:启动协议(⽤于⽆盘设备启动)
• DNS:域名解析协议
当然,也包括你⾃⼰写UDP程序时⾃定义的应⽤层协议;
更多推荐




所有评论(0)