前言
在学习任何一种协议的过程中,在结构上,都应该考虑两点:1.如何分离 2.如何分用
在网络协议栈中,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端口
一个进程可以bind多个端口号,而一个端口号只能bind一个进程,其对应关系数据在操作系统中内核数据中,对应关系类似哈希表的映射关系
二、UDP协议
1.UDP协议端格式
struct udp
{
_u16 source;
_u16 dest;
_u16 len;
_u16 check;
}
- 16 位 UDP 长度, 表示整个数据报(UDP 首部+UDP 数据)的最大长度;
- 如果校验和出错, 就会直接丢弃;
由于UDP是内核级别的数据,大多数操作系统都是基于C语言写的,因此它在传输过程中不需要序列化或者反序列化,对端主机拿到报文之后只需要直接提取协议的8字节数据即可
2.UDP 的特点
UDP 传输的过程类似于寄信.
- 无连接: 知道对端的 IP 和端口号就直接进行传输, 不需要建立连接;
- 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方,UDP 协议层也不会给应用层返回任何错误信息;
- 面向数据报: 不能够灵活的控制读写数据的次数和数量;
面向数据报
应用层交给 UDP 多长的报文, UDP 原样发送, 既不会拆分, 也不会合并;
用 UDP 传输 100 个字节的数据:
- 如果发送端调用一次 sendto, 发送 100 个字节, 那么接收端也必须调用对应的一次 recvfrom, 接收 100 个字节; 而不能循环调用 10 次 recvfrom, 每次接收 10 个字节;
UDP 的缓冲区
- UDP 没有真正意义上的 发送缓冲区. 调用 sendto 会直接交给内核, 由内核将数
据传给网络层协议进行后续的传输动作; - UDP 具有接收缓冲区. 但是这个接收缓冲区不能保证收到的 UDP 报的顺序和
发送 UDP 报的顺序一致; 如果缓冲区满了, 再到达的 UDP 数据就会被丢弃;
UDP 的 socket 既能读, 也能写, 这个概念叫做 全双工
UDP 使用注意事项
我们注意到, UDP 协议首部中有一个 16 位的最大长度. 也就是说一个 UDP 能传输的数据最大长度是 64K(包含 UDP 首部). 然而 64K 在当今的互联网环境下, 是一个非常小的数字. 如果我们需要传输的数据超过 64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;
基于 UDP 的应用层协议
• NFS: 网络文件系统
• TFTP: 简单文件传输协议
• DHCP: 动态主机配置协议
• BOOTP: 启动协议(用于无盘设备启动) • DNS: 域名解析协议
当然, 也包括你自己写 UDP 程序时自定义的应用层协议;



1470

被折叠的 条评论
为什么被折叠?



