【网络】对于我前面UDP博客的补充

UDP

  • 前言
  • 正式开始
    • UDP报文
      • UDP报文
        • 如何将UDP报文和报头进行分离和封装
        • UDP如何将有效载荷交付给上层
        • 如何提取出完整报文
        • 报头是啥
        • 报头中的检验和
      • UDP的特点
      • IO接口
      • 乱序问题
      • UDP是全双工的
      • 注意事项
      • 基于UDP的应用层协议
    • 再次谈论端口
      • 五元组
      • 端口号范围划分
      • netstat
      • xargs

在这里插入图片描述

前言

本篇比较偏理论。基于我前面一篇UDP实践的博客进行补充:【网络】网络编程入门篇——了解接口,快速上手,带你手搓简易UDP服务器和客户端(简易远端shell、简易群聊功能以及跨平台群聊)

主要讲解内容有:

  1. UDP协议报头讲解
  2. UDP协议缓冲区、注意事项等
  3. 五元组
  4. netstat命令讲解

正式开始

UDP报文

下面根据以下内容进行讲解:

  1. 任何协议都要解决两个问题:
    a. 如何分离/封装报头和报文
    b. 如何交付有效载荷
  2. 理解UDP报文本身
  3. 详谈具体报文字段

UDP报文

很简单,就这张图:
在这里插入图片描述

加点东西:
在这里插入图片描述

上面的8字节就是报头,存储了四个字段,每个字段两个字节。

很多教材上都有这张图,但是有的书上详细讲了,有的书没有讲,这里我来讲讲。

如何将UDP报文和报头进行分离和封装

采用定长报头的策略,UDP的报头为8字节的固定长度报头,对端传输层只需要将前8个字节提取出来,剩下的就是有效载荷。(等会说怎么提有效载荷)
在这里插入图片描述

无论是我前面博客中HTTP中用空行来区分报头和有效载荷,还是这里的用定长报头来区分报头和有效载荷,都是协议,双方都要严格遵守,那一层没有遵守哪一层就是一个无用的报文,无法向上交付。

UDP如何将有效载荷交付给上层

提取出报头后,其中有一个字段为目的端口号:
在这里插入图片描述

就通过这个目的端口号进行向上交付,因为进程bind了端口号,我前面写服务端的时候每次端口类型都是uint16_t,即2字节,因为协议中端口号是16位的。

如何提取出完整报文

先读固定长度的报头,报头中有16位的UDP长度字段:
在这里插入图片描述

这个16位的udp长度就是整个报文的长度,假如说是x,整个报文长度为x,报头长度位8,那么有效载荷的长度就是x - 8。读完报头后,再往后读x - 8个字节就行。

所以UDP具有将报文一个一个正确接收的能力。

报头是啥

报头其实就是一个结构体:

struct udp_hdr
{
	uint32_t src_port:16;
	uint32_t dst_port:16;
	uint32_t udp_len:16;
	uint32_t udp_check:16;
}

用结构体实现位段,如果你不懂位段的话可以看看我这篇博客:【C进阶】自定义类型。

再看一下这张图:
在这里插入图片描述

这里为什么要四字节为一行,因为结构体中用的类型是uint32_t,也就是4个字节,这里4个字节就是报头的宽度,所有的报头其实就是一个结构体类型。

封装一个报头,当应用层发来一个报文(就是传输层的有效载荷)时,传输层只需要定义一个udp_hdr对象,将对象中的字段填好,源端口、目的端口、报文长度(应用层的报文大小 + 8)、检验和,然后将这个对象中的数据拷贝到内核的缓冲区中就行。看图:
在这里插入图片描述

向上交付的时候就定义指针就行,报文长度和报头长度都有了,就根据这两个长度读取就行。

这里只是简单的原理,os真正做起来的话要比这复杂的多,毕竟要考虑大小端、平台位数等问题,还是很复杂的。

报头中的检验和

这个检验和不细讲了,说一下有啥用。

接收方UDP检验成功就向上交付,检验失败报文就直接丢弃了,发送方不知道、不重传、不关心。

UDP的特点

其实我前面那篇UDP的博客中也讲过了,这里就再说一下。

  • 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;

如果你看了我前面手搓UDP服务器和TCP服务器的话,你一定懂这句话是什么意思。

因为UDP的服务器只需要这几步:

  1. 创建套接字
  2. bind绑定端口号
  3. recvfrom接收客户端请求并用sendto进行响应

而TCP的服务器是这样的:

  1. 创建套接字
  2. bind绑定端口号
  3. 设置套接字为listen状态
  4. 接收连接
  5. recv/read获取客户端请求并通过write/send进行响应

这里UDP要比TCP少了listen和接收连接这两步,也就是UDP不需要建立连接。

  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息;

下面我截一下前面我UDP博客中的一段话:

屏幕前的你先不要拿这一点来判断谁好谁坏。TCP和UDP都能够存在说明是都能被接受的,各有各的特色。
  先说点UDP不好的,UDP会出现丢包问题,TCP不会出现。不过现在的网络出现丢包问题概率并不大,即使出现了大部分场景下也是可以容忍的。先不要对UDP产生偏见,等会讲的时候你就知道为啥了。
  二者的可不可靠只是二者的特点。并不是单方的缺点。
TCP比UDP可靠,那么TCP就要做更多的工作,可靠性是要靠大量的编码和数据处理工作来实现的,所以TCP想要保证可靠性就一定会使得其在数据通信时为了可靠性而设计出更多的策略,如面向连接、确认应答、超时重传、流量控制、拥塞控制等机制,而这些机制都要靠TCP协议自己来完成,所以说虽然保证了可靠性,但是也就导致了该协议更复杂,维护起来成本更高。

此时UDP就可以对TCP说:咋俩都是协议,你把自己搞那么累干嘛,丢包就丢包了,心放大点,这都不是事,所以UDP只要把数据交给下层就行了,然后就啥也不用管了。而TCP就得管一大堆事,即TCP更安全,UDP更简单。

但是我们大部分情况下传输层协议用的是TCP。像直播、视频这种数据可以用UDP,比如我们有时候看着直播 / 视频时突然卡一下/没声了/屏幕花了等等问题,就可能是因为传输层用的是UDP协议导致丢包了,但是这样就卡一两秒对整体的观看体验影响不大(足球比赛快要进球的时候卡了当我没说😅)。不过有钱的公司也在直播或视频这种资源上也可以用TCP协议,不过TCP协议花费更多,但是能够保证数据的安全,客户能有更好的体验。

  • 面向数据报: 不能够灵活的控制读写数据的次数和数量

IO接口

前面TCP和UDP中IO的接口本质上都是拷贝函数。

TCP的 write、send和read、recv。
UDP的 sendto和recvfrom。

都是拷贝函数。

在这里插入图片描述

所以这里的wirte、send、sendto都不是直接将数据发送到网络当中的,而是将数据拷贝到了内核缓冲区中就完事了,后续工作都是os做的。

TCP和UDP是传输层中应用最广泛的协议,而发送缓冲区(UDP不需要,等会说)和接收缓冲区是由传输层提供的,传输层决定什么时候发,发多少,出错了怎么办的问题,我们无法决定这些问题,就像寄快递一样,你只是把东西交给了快递公司,至于快递啥时候发是快递公司的事情,不是我们操心的。

UDP不需要发送缓冲区,调用sendto只是将数据拷贝给os,os会立即将数据经过网络层、数据链路层发送出去,所以对于发送缓冲区没有特别强的需求。

但是UDP需要接收缓冲区,UDP上面是应用层,应用层就是用户,也就是程序员,需要手动调用recvfrom,但是如果程序员来不及调用呢?同一时刻服务端可能会接收到很多的UDP报文请求,如果某些报文来不及接收,就会先放到接收缓冲区中,所以UDP需要接收缓冲区,但如果缓冲区满了,那么后面到来的报文会被直接丢弃。

乱序问题

如果某一时刻客户端发送了5个报文,如果是按照ABCDE的顺序来发的话,可能会出现接收到的报文为BDCEA的顺序,就像我们在某宝上下单一样,同一天下的单,后面收到的时间不一样,顺序也不一样。

UDP乱序问题通常是因为路由之间的存储转发引起的。解决方法是在发送端的数据段中加入数据报序号的方式,只需要在接收方对数据的头端进行简单排序处理即可。具体步骤如下:

  1. 在发送端的数据段中加入数据报序号。
  2. 接收方接收到数据后,将数据报文按照序号进行排序。
  3. 将排序后的数据报文进行组装,得到完整的数据。

需要注意的是,如果数据报文丢失,可能会导致数据报文序号不连续,因此需要在接收方设置一个超时时间,如果在超时时间内没有收到连续的数据报文,则需要重新请求发送方发送数据报文。

不过这里的做法已经很像TCP了,下一篇博客我会详细讲解TCP。

UDP是全双工的

一个文件描述符,再多线程场景下既可以读也可以写,如何保证呢?
只需要读写缓冲区不冲突就行。

UDP虽然没有发送缓冲区,但是发送时并不会影响接收缓冲区,所以支持全双工。

至于全双工和半双工是啥我实在是不想讲了,前面博客中说了好几次了,不懂的同学搜一下或者翻一下我前面的博客吧。

后一篇要讲的TCP也是全双工的。

注意事项

我们注意到, UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)。然而64K在当今的互联网环境下, 是一个非常小的数字。如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装。

基于UDP的应用层协议

  • NFS: 网络文件系统
  • TFTP: 简单文件传输协议
  • DHCP: 动态主机配置协议
  • BOOTP: 启动协议(用于无盘设备启动)
  • DNS: 域名解析协议

当然, 也包括你自己写UDP程序时自定义的应用层协议;

说说DHCP,当你的电脑没连网的时候,没法上网,本质上是你的电脑没有IP,当连接上WiFi的时候(或者其他能连网方法),电脑会自动获取一个IP地址,这个IP是路由器给的,路由器内部署了DHCP服务,关了电脑之后IP会被自动回收。

再次谈论端口

再我前面写UDP和TCP服务器时,都要让服务端bind一个端口号,客户端也要绑定,但是不需要我们手动绑定,os会自动帮我们做。当本机拿到数据后向上交付时,要根据端口号交付给特定进程。

在这里插入图片描述

系统是如何快速找到端口号对应的进程的呢?
用哈希,可以理解为K值就是端口号,V值就是进程ID,要把有效载荷提供给应用层,就要找到进程的文件描述符,通过文件描述符把有效载荷拷贝到通信的文件中即可,找到文件描述符就先找到进程PCB就行,就这样通过PID找PCB,然后通过PCB找文件描述符。

五元组

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

源IP和源端口号标定发送方的唯一进程。
目的IP和目的端口号标定接收方唯一进程。
协议号可以理解为标定传输层用的是哪一个协议,通常就是TCP或UDP。

这样的一个五元组就可以标定一个通信:
在这里插入图片描述

端口号范围划分

端口号是一个16位的二进制数,所以取值范围为0~65535。

0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
就像是110就是警察,120就是急救,119就是火警一样。

有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些固定的端口号:

  • ssh服务器, 使用22端口
    ftp服务器, 使用21端口
    telnet服务器, 使用23端口
    http服务器, 使用80端口
    https服务器, 使用443端口

/etc/services里面存放了常见端口号。
在这里插入图片描述

不要随意绑定0 ~ 1023的端口号。

1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的。我们自己也能选择其中的进行绑定。像我前面我在搞服务器的时候端口号用的基本上都是8080。

netstat

netstat是一个用来查看网络状态的重要工具.
语法:netstat [选项]
功能:查看网络状态
常用选项:

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

在这里插入图片描述
这里查看的时候带的选项是natp。

n就是能显示成数字的就显示成数字,看第二行的sshd,如果我这里去掉n:
在这里插入图片描述
就变成了ssh,上面将协议固定端口的时候也说了,ssh的端口就是22。

a就是把状态为listen的也显示,我去掉a之后:
在这里插入图片描述

t就是显示tcp的服务,t换成u就是显示udp的服务:
在这里插入图片描述

p就是显示进程和其PID,也就是最后面的字段,去掉:
在这里插入图片描述

这里udp在接收服务的时候不会进行listen,至于什么原因我前面的博客中有,代码写过就知道了。

再看回来前面的这张图:
在这里插入图片描述

来看看sshd进程:
在这里插入图片描述

这个进程是一个守护进程(前面博客讲过,不懂点链接:【网络】用代码讲解协议 + 序列化和反序列化 + 守护进程 + jsoncpp),大部分以d结尾的进程一般都是守护进程(d就是daemon),三个ID相同,父进程是1os。

我这里用的是云服务器,登录的时候sshd会在终端为我开一个bash进程,并让我输入指令,输入后就将字符串发送给远在异地(北京、广东等)的服务器执行,并将执行后的结果返回。

xargs

这是一个命令行上的东西,可以将标准输入的内容转为命令行参数。

比如说我用pidof来获取一个进程的pid,然后用管道 + args交给kill命令,就可以关掉这个进程。
在这里插入图片描述

kill命令想使用的话必须得是命令行参数来搞,管道传输的数据是通过文件(标准输入)来实现的,没法直接给成命令行参数:
在这里插入图片描述
这里管道会将pidof的结果转成标准输入送给kill -9,但是kill -9执行的时候是将各个字段通过命令行参数来交给进程的,标准输入和命令行参数没有啥关系,无法直接执行kill命令,但是xargs会将标准输入的转成命令行参数,这样就可以传给进程执行了。

再比如说ls | xargs touch可以更新所有文件的ACM时间,改成最新的时间:
在这里插入图片描述

UDP比较简单,没有什么好讲的,你只要能写出我前面简易UDP服务器,懂本篇所讲的UDP报头就行。

到此结束。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt之QtConcurrent】描述及使用

描述 QtConcurrent是一个Qt库中的模块&#xff0c;用于实现多线程并发编程。它提供了一些高级API&#xff0c;使得在多核处理器上并行执行代码变得更加容易。 示例&#xff1a; 使用的话&#xff0c; 需要在pro文件中添加&#xff1a;QT concurrent模块。 #include <QC…

山东大学开发可解释深度学习算法 RetroExplainer,4 步识别有机物的逆合成路线

逆合成旨在找到一系列合适的反应物&#xff0c;以高效合成目标产物。这是解决有机合成路线的重要方法&#xff0c;也是有机合成路线设计的最简单、最基本的方法。 早期的逆合成研究多依赖编程&#xff0c;随后这一工作被 AI 接替。然而&#xff0c;现有的逆合成方法多关注单步逆…

手机桌面待办事项APP推荐

每天&#xff0c;我们每个人都面临着繁琐的事务和任务&#xff0c;而手机成了我们日常生活中不可或缺的伙伴。手机上的待办事项工具像一个可靠的助手&#xff0c;可以帮助我们更好地记录、管理和完成任务。在手机桌面上使用的待办事项APP推荐用哪一个呢&#xff1f; 手机是我们…

微信h5支付配置,商家存在未配置的参数,请联系商家解决

对于PC端来说&#xff0c;只需要开通 native支付 就可以了 但手机端h5还需要配置支付域名&#xff0c;并且域名只需要配置一级就可以了&#xff0c;比如&#xff1a;a.test.com, b.test.com, 只需要配置 test.com 就能满足所有的二级域名了, 而不需要配置a.test.com或者b.te…

网工内推 | 国企,解决方案工程师,最高30k,有软考证书优先

01 中电信数智科技有限公司海南分公司 招聘岗位&#xff1a;解决方案经理&#xff08;ICT&#xff09; 职责描述&#xff1a; 1、负责调动前后端资源做好全省ICT业务的售前支撑服务工作。 2、根据实际项目需求&#xff0c;主动协同客户渠道开展ICT项目商机挖掘&#xff0c;促进…

c++视觉检测------Shi-Tomasi 角点检测

Shi-Tomasi 角点检测 &#xff1a;goodFeaturesToTrack() goodFeaturesToTrack() 函数是 OpenCV 中用于角点检测的功能函数。它的主要作用是检测图像中的良好特征点&#xff0c;通常用于计算机视觉任务中的光流估算、目标跟踪等。 函数签名&#xff1a; void goodFeaturesTo…

华为ERP,包含哪些内容?技术的先进性体现在哪里?

华为作为全球领先的信息和通信技术&#xff08;ICT&#xff09;解决方案提供商&#xff0c;其企业资源规划&#xff08;ERP&#xff09;系统是一个高度复杂且集成的管理软件平台&#xff0c;用于优化公司内部的业务流程和资源分配。华为ERP系统包括一系列模块和功能&#xff0c…

代码审计及示例

简介&#xff1a; 代码安全测试是从安全的角度对代码进行的安全测试评估。 结合丰富的安全知识、编程经验、测试技术&#xff0c;利用静态分析和人工审核的方法寻找代码在架构和编码上的安全缺陷&#xff0c;在代码形成软件产品前将业务软件的安全风险降到最低。 方法&#x…

论文阅读 - Hidden messages: mapping nations’ media campaigns

论文链接&#xff1a; https://link.springer.com/content/pdf/10.1007/s10588-023-09382-7.pdf 目录 1 Introduction 2 The influence model 2.1 The influence‑model library 3 Data 4 Methodology 4.1 Constructing observations 4.2 Learning the state‑transiti…

【Maven】Unknown lifecycle phase “.skip.test=true“.

idea 终端执行如下命令时 mvn clean install -Dmaven.skip.testtrue报&#xff1a; Unknown lifecycle phase ".skip.testtrue". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id&…

修炼k8s+flink+hdfs+dlink(六:学习namespace,service)

一&#xff1a;什么是namespace&#xff1f; 你可以认为namespaces是你kubernetes集群中的虚拟化集群。在一个Kubernetes集群中可以拥有多个命名空间&#xff0c;它们在逻辑上彼此隔离。 他们可以为您和您的团队提供组织&#xff0c;安全甚至性能方面的帮助&#xff01; 二&a…

【20年VIO 梳理】

19-20年VIO 梳理 1. 开源代码介绍&#xff1a; DSM2. FMD Stereo SLAM&#xff1a;融合MVG和直接方法&#xff0c;实现准确&#xff0c;快速的双目SLAM3. 基于VINS-Mono开发的SPVIS4. 改进&#xff1a;一种基于光流的动态环境移动机器人定位方案5. PVIO:基于先验平面约束的高效…

吃瓜教程3|决策树

ID3算法 假定当前样本集合D中第k类样本所占比例为pk&#xff0c;则样本集合D的信息熵定义为 信息增益 C4.5算法 ID3算法存在一个问题&#xff0c;就是偏向于取值数目较多的属性&#xff0c;因此C4.5算法使用了“增益率”&#xff08;gain ratio&#xff09;来选择划分属性 CA…

深入浅出排序算法之希尔排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每一组内的记录进行排序。然后&#xf…

警报:Citrix和VMware漏洞的PoC利用代码已发布

导语 近日&#xff0c;虚拟化服务提供商VMware向客户发出警报&#xff0c;称其Aria Operations for Logs中的一个已修补安全漏洞的PoC利用代码已经发布。这个高危漏洞&#xff08;CVE-2023-34051&#xff09;是一种绕过身份验证的情况&#xff0c;可能导致远程代码执行。本文将…

零基础Linux_23(多线程)线程安全+线程互斥(加锁)+死锁

目录 1. 线程安全 1.1 线程不安全前期 1.2 线程不安全原因 2. 线程互斥 2.1 加锁保护&#xff08;代码&#xff09; 2.2 锁的本质 3. 可重入对比线程安全 4. 死锁 4.1 死锁的必要条件 4.2 避免死锁 5. 笔试面试题 答案及解析 本篇完。 1. 线程安全 基于上一篇线程…

vue项目中内嵌iframe,打包上线时候iframe地址如何写?

vue项目中内嵌iframe&#xff0c;打包上线时候iframe地址如何写 一、项目结构1.内嵌的iframe文件位置2.打包后的iframe的位置 二、代码 前提描述&#xff0c;项目是用webpack打包的&#xff0c;内嵌一个完整的js小组件 一、项目结构 1.内嵌的iframe文件位置 2.打包后的iframe的…

Pytorch代码入门学习之分类任务(三):定义损失函数与优化器

一、定义损失函数 1.1 代码 criterion nn.CrossEntropyLoss() 1.2 损失函数简介 神经网络的学习通过某个指标表示目前的状态&#xff0c;然后以这个指标为基准&#xff0c;寻找最优的权重参数。神经网络以某个指标为线索寻找最优权重参数&#xff0c;该指标称为损失函数&am…

【开发篇】一、处理函数:定时器与定时服务

文章目录 1、基本处理函数2、定时器和定时服务3、KeyedProcessFunction下演示定时器4、process重获取当前watermark 前面API篇完结&#xff0c;对数据的转换、聚合、窗口等&#xff0c;都是基于DataStream的&#xff0c;称DataStreamAPI&#xff0c;如图&#xff1a; 在Flink…

宏电5G RedCap工业智能网关获首个中国移动5G物联网开放实验室5G及轻量化产品能力认证

10月21日&#xff0c;2023世界物联网博览会——中国移动物联网开发者大会暨物联网产业论坛在无锡圆满举行。宏电股份参与中国移动5G物联网开放实验室5G及轻量化产品能力认证成果授牌仪式&#xff0c;并获得认证证书。 此次认证主要对产品功能、产品性能、RedCap网络兼容性进行测…
最新文章