当前位置: 首页 > news >正文

Linux网络编程:传输层协议|UDP

知识引入:

端口号:

当应用层获得一个传输过来的报文时,这时数据包需要知道,自己应该送往哪一个应用层的服务,这时就引入了“端口号”,通过区分同一台主机不同应用程序的端口号,来保证数据传输的可靠性!

而我们在之前的学习知道,ip地址是唯一的地址标识,那么我们借助ip地址和端口号是不是就能找到网络中唯一的一台主机?答案是肯定的,这也就是传输层协议存在的意义之一!

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

如图我们通过源ip和源端口号,就知道信息是从哪来的,知道了目的ip和目的端口号就知道信息是去往哪里的。那么就能够实现网络中唯二的两个进程通过网络进行进程间通信了!!!


端口号划分:

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

查看网络连接状态命令:

// -ntpl n-带数字 t-TCP协议 p-服务名称 l-只查看listen服务
sudo netstat -ntpl
// ss命令也可以查网络服务
ss -nltp

常用选项:

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

UDP协议

UDP协议端格式

如图:UDP协议报文前8字节为UDP协议的报头,后面的即为有效载荷。

我们知道网络传输需要解决的四个问题:

  • 报文如何将报头和有效载荷分离
  • 有效载荷如何向上交付给对应应用层程序
  • 报文内容是否完整
  • 报文内容是否有误

联系UDP协议格式,我们发现以上四个问题对应:

  • 解析固定报头长度来分开报头和有效载荷
  • 再通过目的端口号将有效载荷交付给应用层服务
  • 16位UDP长度对应着报文的长度(当长度不符时,直接丢包)
  • 而16位UDP检验和检测是否在传输过程中出现0变成1、1变成0

通过UDP协议报头的设计,那么我们就解决了网络传输的4个问题,而在这里我们也能理解报头(协议)是一个结构化字段。

struct UdpHeader
{uint32_t src_port:16;uint32_t dest_port:16;uint32_t length:16;uint32_t check_sum:16;
}

又因为传输层是实现在操作系统中,也就是操作系统需要维护获得的UDP报文,需要对UDP报文实现“先描述再组织”

如图为:发送端如何形成UDP报文结构示意

  1.  首先应用层需要存在报头的结构化对象和管理报文信息的sk_buff结构化对象
  2. 当用户准备通过sendto进行发送时,通过bind函数将对应端口号写入进报头信息中,另外有效载荷写入sk_buff指向的缓冲区中,这时有tail执行有效载荷的尾,_data指向有效载荷的头部(_data-_tail即为有效载荷的长度)
  3. 传输层首先将_data向左移动8个字节,给UDP的报头放入,接着完善报头中的报文长度信息和check_num(可能是一种哈希映射)
  4. 最终就形成了一段UDP报文

因为系统中可能存在多份待发送的UDP报文,所以我们需要通过数据结构来管理这些报文。最终UDP协议就实现了!!!

当接收端接收到UDP报文时:

  1. 先分开报头和有效载荷(通过分离前8个字节数据),然后读取报头中的报文长度,就能找到有效载荷
  2. 通过对有效载荷进行哈希散列,判断前后的check_num是否相等,不相等就丢弃报文。
  3. 获取到报文后就可以通过对应端口,找到接受端的应用层服务

最终我们就完成了UDP通信!!!

UDP的特点

UDP传输的过程类似于寄信,为什么这么说呢,这和UDP的特点有关

  • 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层 返回任何错误信息;
  • 面向数据报: 不能够灵活的控制读写数据的次数和数量;(应用层交给UDP多长的报文, UDP原样发送, 既不会拆分, 也不会合并; )

 我们在传输报文时,只要知道对端的地址就可以进行传输,不需要事先通知对方才能够寄信。另外,当我们写信出去后我们就无法获得这封信的状态,除非他被对方收到,并且返回收到信息给你。最终,信的寄和读都是一次的行为,跟你信里面写了多少内容无关,是一个整体。


值得注意的是:UDP协议允许报文最长为16位,也就是64k的大小,当我们传输的内容大于64k时,我们就需要多次将数据分为64kb的报文,接着不断传输。

相关文章:

  • yolox-何为EMA?
  • JAVA生成随机姓名(小白也能看得懂)
  • IDEA2023.2单击Setting提示报错:Cannot get children Easy Code
  • 【论文解读】A Progress Report: The Alliance for Open Media and the AV1 Codec
  • odoo16版本的render变更
  • 学习Uni-app开发小程序Day23
  • 06.部署jpress
  • Sublime Text 基础教程(个人总结)
  • 机器学习之爬山算法(Hill Climbing Algorithm)
  • 【OpenVINO™】在C#中使用 OpenVINO™ 部署 YOLOv10 模型实现目标
  • 多线程笔记
  • 浙江大学数据结构MOOC-课后习题-第九讲-排序3 Insertion or Heap Sort
  • git多人开发,不用merge的操作方法,阿里codeup
  • 柳宗元,政治坎坷与文学辉煌的交织
  • 多线程基本常识
  • 【Leetcode】101. 对称二叉树
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • leetcode388. Longest Absolute File Path
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Redis 中的布隆过滤器
  • vue-cli在webpack的配置文件探究
  • vue数据传递--我有特殊的实现技巧
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 前端存储 - localStorage
  • 网络应用优化——时延与带宽
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (k8s)kubernetes 部署Promehteus学习之路
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (备忘)Java Map 遍历
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)c++ std::pair 与 std::make
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .NetCore项目nginx发布
  • .NET成年了,然后呢?
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .NET中的Exception处理(C#)
  • @Bean, @Component, @Configuration简析
  • @FeignClient注解,fallback和fallbackFactory
  • [2023年]-hadoop面试真题(一)
  • [5] CUDA线程调用与存储器架构
  • [AI Google] 使用 Gemini 取得更多成就:试用 1.5 Pro 和更多智能功能
  • [AIGC] Kong:一个强大的 API 网关和服务平台
  • [Android Studio 权威教程]断点调试和高级调试