Linux--传输层协议UDP

news2024/11/24 20:08:29

目录

传输层

再谈端口号

端口号范围划分

认识知名端口号(Well-Know Port Number)

两个问题

 UDP 协议

UDP 协议端格式

UDP 的特点

面向数据报

UDP 的缓冲区

UDP 使用注意事项

基于 UDP 的应用层协议

进一步理解UDP协议 


传输层

负责数据能够从发送端传输接收端.

再谈端口号

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

在 TCP/IP 协议中, 用 "源 IP", "源端口号", "目的 IP", "目的端口号", "协议号" 这样一个
五元组来标识一个通信(可以通过 netstat -n 查看);


端口号范围划分

• 0 - 1023: 知名端口号, HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的
端口号都是固定的.
• 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作
系统从这个范围分配的


认识知名端口号(Well-Know Port Number)

有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些
固定的端口号:
• ssh 服务器, 使用 22 端口
• ftp 服务器, 使用 21 端口
• telnet 服务器, 使用 23 端口
• http 服务器, 使用 80 端口
• https 服务器, 使用 443
执行下面的命令, 可以看到知名端口号


cat /etc/services

我们自己写一个程序使用端口号时, 要避开这些知名端口号


两个问题

1. 一个进程是否可以 bind 多个端口号?一个进程可以绑定多个端口号。

        在网络编程中,一个进程可能需要监听多个端口以接收来自不同客户端或服务的连接请求。例如,一个Web服务器可能同时监听80端口(用于HTTP)和443端口(用于HTTPS)。这通常通过创建多个套接字(socket)并分别将它们绑定到不同的端口号来实现。
2. 一个端口号是否可以被多个进程 bind?

        但一个端口号只能被一个进程bind,因为端口号是为了确定网络中进程的唯一性的,如果多个进程尝试绑定同一个端口号,操作系统通常会返回错误,因为这会导致数据接收的混乱。

如何理解?

        可以把端口号和进程理解成哈希关系,端口号是key值,一个key对应的value是唯一的,但一个value可以被多个key值所访问。

 UDP 协议

UDP 协议端格式

• 16 位 UDP 长度, 表示整个数据报(UDP 首部+UDP 数据)的最大长度;
• 如果校验和出错, 就会直接丢弃;

•udp的报头是一个结构体,源代码:

  • UDP报头结构
    • 源端口(16位) 
    • 目的端口(16位)
    • 长度(16位):UDP报头和数据的长度(以字节为单位)
    • 校验和(16位):用于错误检测的可选字段
  • 封装过程
    1. 创建一个UDP报头,并填充源端口、目的端口、长度和校验和。
    2. 将有效载荷数据附加到UDP报头之后。
    3. 计算整个UDP数据报的校验和(如果需要)。
    4. 将完整的UDP数据报传递给IP层进行进一步封装和发送。

分用指的是从接收到的UDP数据报中提取出有效载荷数据的过程。这通常发生在接收数据时。

  • 分用过程
    1. 从接收到的IP数据报中提取出UDP数据报。
    2. 验证UDP报头的校验和(如果需要)。
    3. 使用UDP报头中的长度字段来确定有效载荷数据的长度。
    4. 提取出有效载荷数据,并将其传递给上层应用程序进行处理。

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协议 

1.udp报头

        报头就是一个结构体变量:struct udphdr hadr={...}.,将报头构建好了发出去,对方也一定有一快内存空间来接受报头,物理内存会拿到报头的二进制数据,那么接收方想拿到udp中的报文,那么就直接定义指针指向它就行了:struct udphdr *h,就可以任意取其中的字段了。

        所以双方就行udp协议的交换时,就是直接用结构体对二进制流的序列化和反序列化。

2.对报文的理解

        udp存在缓冲区,所以决定了上层我们正在处理数据的时候(1.正在处理的报文),底层也一定2.有报文没有被处理,被缓冲区缓存了,3.此时OS也不断地从硬件中读取报文,当然还有4.准备放到缓冲区的报文。

        当然操作系统内可能存在读取的多份报文,但还没有及时向上交付。所以在系统中,存在大量的报文,正在等待被向上交付,也存在正在被向下交付的报文。那这些报文哪些是向下交付的呢?哪些又是向上交付的呢?哪些是要等在被创建的?哪些又是等待被删除的?操作系统一定是要对报文进行管理的(先描述,再组织),OS存在管理报文的结构体:

struct sk_buff

        

下面是 struct sk_buff 中一些主要成员的简要说明:

  1. 数据相关
    • char *head, *data, *tail, *end:这些指针用于描述数据缓冲区。head 指向缓冲区的起始位置,data 指向实际数据的开始位置,tail 指向实际数据的结束位置,end 指向缓冲区的末尾。
  2. 元数据
    • unsigned int len, data_lenlen 表示从 data 到 tail 的长度,即实际数据的长度;data_len 表示从 data 到 end 的长度,即整个缓冲区中可用于数据的长度。
    • unsigned int truesize:表示 sk_buff 结构体及其数据缓冲区的总大小。
  3. 控制信息
    • __u32 priority:报文的优先级。
    • __be16 protocol:报文使用的协议类型。
    • __u32 mark:用于标记报文,以便在路由或过滤时使用。
  4. 链表相关
    • struct sk_buff *next, *prev:用于将多个 sk_buff 结构体链接成一个链表,表示一个完整的报文(如果报文太大,无法在一个 sk_buff 中表示)。
  5. 时间戳
    • ktime_t tstamp:报文的时间戳。
  6. 其他
    • void (*destructor)(struct sk_buff *skb):一个函数指针,用于在 sk_buff 被释放时执行清理工作。

        在传输层中会给每个报文形成一个缓冲区struct sk_buff会管理这段缓冲区 ,在添加数据之前,可能需要预留一定的空间用于存放报头或对齐数据。所以head和data一开始不是指向头的,一开始指向的是从应用层拷贝数据在缓冲区预留的空间的头,也就是有效载荷的头,接着添加报头的时候head指针会向前移动一个sizeof(struct udphdr)的大小,接着会填充报头的数据。这样就构建好了一个报文。

        struct sk_buff中存在struct sk_buff *next, *prev,将多个 sk_buff 结构体链接成一个链表,只要找到链表的头就获取到了整个报文,对报文进行链式处理。再将报文交给下层只需要将struct sk_buff结构交给下一层,继续以相同的方法添加报文。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045854.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32F407ZET6使用LCD(9341)

1.原理图 屏幕是中景园2.8寸液晶屏,9341驱动不带触摸屏版本 2.STM32CUBEMX配置 3.编写驱动程序

【全国大学生电子设计竞赛】2021年K题

🥰🥰全国大学生电子设计大赛学习资料专栏已开启,限时免费,速速收藏~

02 网络编程-UDP用户数据包协议

目录 一、UDP简介 二、UDP协议的通信流程 三、UDP相关API接口 (1)创建套接字-socket() (2)地址信息结构体sockaddr_in{} (3)地址转换接口 (4)发送消息sendto() (…

谁偷偷看了你的网站?这两款统计工具告诉你!小白易上手~

前两天,上线了一个知识库网站:花了一天时间,搭了个专属知识库,终于上线了,手把手教,不信你学不会。 想知道这个网站的流量如何,怎么搞? 网站流量统计分析工具,了解下&a…

EmguCV学习笔记 C# 2.2 Matrix类

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 EmguCV学习笔记目录 Vb.net EmguCV学习笔记目录 C# 笔者的博客网址:VB.Net-CSDN博客 教程相关说明以及如何获得pdf教…

全面解析Gerapy分布式部署:从环境搭建到定时任务,避开Crawlab的坑

Gerapy分布式部署 搭建远程服务器的环境 装好带docker服务的系统 Docker:容器可生成镜像,也可拉去镜像生成容器 示例:将一个环境打包上传到云端(远程服务器),其他8个服务器需要这个环境直接向云端拉取镜像生成容器,进而使用该环境,比如有MYS…

ElasticSearch读写性能调优

文章目录 ES写入数据过程ES读取数据的过程写数据底层原理提升集群读取性能数据建模优化分片 提升写入性能的方法服务器端优化写入性能建模时的优化降低Translog写磁盘的频率,但是会降低容灾能力分片设定调整Bulk 线程池和队列 ES写入数据过程 客户端选择一个node发…

Linux系统编程:进程间通信 1:管道

1.进程间的互相通信的方式 进程间互相通信的方式共有7种: (1)无名管道(同主机) (2)有名管道(同主机) (3)信号(同主机)…

大语言模型(LLM)构建产品的一年经验总结【干货长文】

这是一份涵盖战术、运营和战略方面的大语言模型产品成功建设的实用指南。 现在是构建大型语言模型(LLM)的激动人心的时刻。在过去的一年里,LLM已经变得足够好,可以用于实际应用。而且它们每年都在变得更好更便宜。伴随着社交媒体上…

成功转行软件测试工程师,年薪30W+,经验总结都在这!

这是给转行做软件测试的小白的参考,无论是从零开始,或者是转行的朋友来说,这都是值得一看的,也是可以作为一种借鉴吧。 而且我决定转行IT(互联网)行业,其实理由也很简单,不用动体力…

全网爆火的从零到一落地接口自动化测试

前段时间写了一系列自动化测试相关的文章,当然更多的是方法和解决问题的思路角度去阐述我的一些观点。结合我自己实践自动化测试的一些经验以及个人理解,这篇文章来聊聊新手如何从零到一落地实践接口自动化测试。 为什么要做接口测试 测试理念的演变 早…

awesome-react-native 收集最好的React Native库,工具,教程,文章(上篇)

image 分类 分类 会议 连锁反应 - 波特兰,或者美国React Native EU - 弗罗茨瓦夫,波兰React Alicante - 西班牙阿利坎特ReactNext - 以色列特拉维夫React Berlin - 柏林,德国 用品 参考HOWTO文档什持续集成内幕 组件 UI 导航 导航/路由文章…

Aerospike学习笔记

1 概述 Aerospike 是一个分布式、可扩展的数据库。该架构具有三个关键目标: 为网络规模的应用程序创建灵活、可扩展的平台。提供传统数据库所期望的稳健性和可靠性(如 ACID)。以最少的人工参与提供运营效率。 文档链接:https://d…

【Linux —— 理解pthread库和底层逻辑】

Linux —— 理解pthread库和pthread_t 理解pthread库pthread库是一个动态库底层逻辑 LWPpthread_tpthread_t的概念pthread_t 的实现pthread_t 与 LWP 的关系 独立的栈空间管理 理解pthread库 pthread库是一个动态库 使用下面指令可以查找的系统目录下的库信息 ls /lib/x86_6…

海康VisionMaster使用学习笔记2-相机取图及参数设置

相机取图及参数设置 1. 关联相机-相机管理界面 除了以上两类外,第三方相机都可以通过全局相机进行连接 2. 相机参数设置 相机连接 跨网段IP,枚举 图像缓存数量 实时取流,断线重连 只有支持组播的相机才可以实时取流 触发设置 触发源 LINE0 可以保护电路 LINE2 可配置输入输出…

笔记(day21) 多线程以及锁的概念(超级完整版)

一、 多线程 1.1 程序,进程,线程 程序:一堆命令的集合,完成某个特定任务,是静态的,保存在硬盘中 进程:是程序的一次执行过程,就是把程序载入内存中执行,就是进程,是动态的 线程:是进程进一步细化,是程序内部的一条执行分支 如果一个进程同一时间执行多个线程,就是支持多线程 我…

简单测试AOP五种增强执行时机

1. 目标方法类,spring代理bean Component public class Test {public void test(){System.out.println("test 目标方法");}public void testException(){throw new RuntimeException();} } 2. 配置类 Configuration ComponentScan EnableAspectJAutoPr…

查询满足连续任意30天的全量交易的多个商户

需求说明: 先说表结构把,就是一张订单表存了商户号和其他相关信息,现在要查询这个订单表中以商户为主体的连续交易,也就是每天产生至少一笔订单的商户才算连续,不知道看到的小伙伴有没有什么想法和头绪,在一…

【C++进阶】map与set的封装实践

文章目录 map和setmapmap的框架迭代器operator()operator--()operator()和operator!()operator*()operator->() insertbegin()end()operator[] ()map的所有代码: set的封装迭代器的封装总结 map和set 通过观察stl的底层我们可以看见,map和set是通过红…

ubuntu16.04安装ibus拼音 输入法

前言 开始尝试搜狗输入,发现问题很多,放弃。网上说ibus比较稳定,决定安装ibus输入法。 步骤 安装ibus,使用如下命令, 安装完重启系统,使ibus生效; sudo apt install ibus ibus-pinyin ibus-table ibus-…