【Linux网络编程】传输层协议-----UDP协议

文章目录

一、前置知识了解:

1、传输层意义:

应用层的协议并不是简单地将请求和响应直接发送到网络中的,而是将数据通过网络协议栈自顶向下进行传输,通过传输层,网络层,数据链路层,最后通过硬件在网络中进行通信的

在之前的学习中,HTTP/HTTPS这些应用层协议是保证数据安全的,而现在所学的传输层是了保证数据能够可靠地传送到目标地址

2、端口号:

端口号标识了一个主机上进行通信的不同的应用程序

当一台主机接受到了数据,然后从下往上依次传输,但是这个数据应该是给哪个进程的,就由数据中的目的端口号来决定,这个操作是在传输层进行的,在传输层会提取出数据中的端口号,然后将数据给对应进程

端口号划分:

端口号的长度是16位,因此端口号的范围是0 ~ 65535:

0 ~ 1023:知名端口号。比如HTTP,FTP,SSH等这些广为使用的应用层协议,它们的端口号都是固定的

1024 ~ 65535:操作系统动态分配的端口号。客户端程序的端口号就是由操作系统从这个范围分配的

一个端口号是否可以被多个进程绑定?

一个端口号绝对不能被多个进程绑定,因为端口号的作用就是唯一标识一个进程,如果绑定一个已经被绑定的端口号,就会出现绑定失败的问题
一个进程是否可以绑定多个端口号?

一个进程是可以绑定多个端口号的,这与"端口号必须唯一标识一个进程"是不冲突的,只不过现在这多个端口唯一标识的是同一个进程罢了

我们限制的是从端口号到进程的唯一性,而没有要求从进程到端口号也必须满足唯一性,因此一个进程是可以绑定多个端口号的

3、五元组标识一个通信:

在TCP/IP协议中,用源IP源端口号目的IP目的端口号协议号这样一个五元组来标识一个通信

4、netstat

其作用是:查看网络状态
选项:

  • n:拒绝显示别名,能显示数字的全部转换成数字
  • l:仅列出处于LISTEN(监听)状态的服务
  • p:显示建立相关链接的程序名
  • t(tcp):仅显示tcp相关的选项
  • u(udp):仅显示udp相关的选项
  • a(all):显示所有的选项,默认不显示LISTEN相关

5、pidof:

通过进程名来查看服务器进程的 pid

二、UDP协议:

1、UDP协议格式:

对于UDP来说,无论发多大的数据,报头的大小是固定的,所以对UDP来说,将报头和有效载荷进行分离只需拿走前8个字节即可

报头解析:

源端口和目的端口:

当我们从一台主机向另一台主机发送你好的时候,你好就是UDP协议中的数据,然后操作系统就会自动给我们的数据添加报头,源端口就是发送方的端口号, 目的端口就是目标主机的端口号

客户端怎么知道源端口和目的端口的呢?
源端口号 :对于客户端的端口号来说,这是随机的,在启动客户端的进程的时候,操作系统会从主机中空余的端口号随机一个进行使用
目的端口号:目的端口号,也就是服务端的端口号,服务端的端口号一般是不变的,并且同一个应用的客户端和服务端开发也是同一个团队,所以也就会知道服务端的端口号,它会在编写的时候就内置在客户端中,当客户端进行connect的时候,链接的就是这个内置的端口号
服务端怎么知道源端口和目的端口的呢?

客户端在发送数据前,会通过操作系统的套接字(Socket)接口创建连接,此时,操作系统会为客户端随机分配一个源端口号,并将其与用户指定的目的端口号(即服务端监听的端口)一起,封装到 TCP 报文的首部中,当服务端的传输层拿到报文后,进行报文和有效载荷分离,这样就能够拿到客户端封装在报文中的源端口和目的端口了

UDP长度和UDP检验和:

UDP长度:表示整个数据报(UDP首部+UDP数据)的长度,起作用是帮助我们知道当前数据是一个完整的报文,有了整个报文的长度, 有效载荷的长度直接使用报文长度减去8字节就行了

UDP检验和:UDP报文的检验和出错,就会直接将报文丢弃

如何理解报头:

Linux操作系统是通过C语言写的,对于协议来说,可以把它看作是一种约定,所以这就是一种C语言版本的struct结构体的位段类型(不是结构体)

位段和结构体

特性 结构体(Struct) 位段(Bit Field)
内存分配 按字节 / 类型分配,可能有对齐 按位分配,成员可共享字节
内存效率 较低(可能有浪费) 较高(适合小数据)
适用场景 一般数据存储,注重直观性 节省内存场景(如标志、寄存器)
访问限制 无特殊限制,可取地址 不可取地址,跨平台兼容性差
c 复制代码
struct udp_header
{
    uint32_t src_port:16;
    uint32_t dst_port:16;
    uint32_t length:16;
    uint32_t check_code:16;
};

既然是类型,那么就可以定义变量,那么以后我们定义udp报头,其实就是创建一个这个类型的变量

2、面向数据报

应用层交给UDP多长的报文,UDP就原样发送,既不会拆分,也不会合并,这就叫做面向数据报

别人发了三个快递,那么我们就一定要收到三个,不会出现只收到一个,一个半这样的情况。如果只有一个包裹,那我们也不能只拿走一半

如果发送端调用一次sendto, 发送100字节, 那么接收端也必须调用对应的一次recvfrom, 接收100字节;而不能循环十次调用recvfrom, 每次接受10字节

结论:发送了一个报文,要么不读,要么 recvfrom 等到读取完一整个报文再返回

3、UDP缓冲区:

UDP没有真正意义上的发送缓冲区,因为它没有可靠机制,不需要把数据暂存起来,它直接调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作

UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃

UDP的socket既能读,也能写,因此UDP是全双工

为什么UDP要有接收缓冲区:

临时存储已到达但尚未被应用程序读取的 UDP 数据包,相当于 "临时仓库",让应用程序可以按照自己的节奏从缓冲区中读取数据,避免因处理速度不足导致的数据包丢失

如果 UDP 没有接收缓冲区,那么就要求上层及时将 UDP 获取到的报文读取上去,如果一个报文在 UDP 没有被读取,那么此时 UDP 从底层获取上来的报文数据就会被迫丢弃

相关推荐
Mr. Cao code7 小时前
探索OpenResty:高性能Web开发利器
linux·运维·服务器·前端·nginx·ubuntu·openresty
Nuyoah11klay8 小时前
华清远见25072班网络编程day1
linux·服务器·网络·网络编程
努力学习的小廉8 小时前
深入了解linux系统—— 日志
linux·运维·服务器
MilesShi11 小时前
从 scheduler_tick 到上下文切换:深入解析 Linux 内核的 TIF_NEED_RESCHED 标志设置流程
linux·运维·单片机
liulilittle14 小时前
OPENPPP2 —— IP标准校验和算法深度剖析:从原理到SSE2优化实现
网络·c++·网络协议·tcp/ip·算法·ip·通信
我爱云计算14 小时前
K8S详解(5万字详细教程)
linux·运维·云原生·容器·kubernetes
北极光SD-WAN组网16 小时前
从0到1搭建某铝箔智慧工厂网络:5G与WiFi 6助力智能制造
网络·5g·制造
阿昭L16 小时前
HTTP原理
网络·网络协议·http
2301_7943339117 小时前
实验室服务器配置|通过Docker实现Linux系统多用户隔离与安全防控
linux·服务器·docker·实验室