Linux学习之Tcp与Udp

目录

UDP

Udp协议的格式

UDP的传输特性

UDP的缓冲区

  基于UDP的应用层协议

 TCP协议

TCP的报文格式

1.ACK确认应答机制

2.超时重传

3.TCP的链接管理机制

为什么要三次握手呢?

理解TIME_WAIT状态

 流量控制(可靠性+效率)

滑动窗口

拥塞控制

TCP的特点


UDP

我们系看看udp协议:

Udp协议的格式

 UDP报文一共16字节,由UDP首部和UDP数据组成,在进行校验时,如果校验出错,就会选择丢弃。

首部格式:8字节
源端口:2字节
目的端口:2字节
长度:2字节,含UDP首部和载荷
校验:2字节

UDP的传输特性

 UDP的传输过程类似于寄信。

UDP在传输信息时,如果检验出错,就会丢弃报文,并不会通知对方,因此传输特性为:

无连接性:传输数据时,是不会向对方请求建立连接的,直到ip地址和端口号就进行传输。

不可靠:因为无连接,那么数据在传输过程中,是无法保证能准确到达目的地,没有确认机制,也没有重传机制,如果校验有错,报文直接就没了,也不知到原因,也收不到。

面向数据报:不能够灵活的控制读写数据的次数和数量。每次发送数据都可以认为是再发邮件,且要一次就把邮件的内容全读取到。

 在我们之前学习Tcp套接字的时候,我们知道Tcp在数据传输过程中,是要去定制协议的,每一次都需要对发送或者读取的数据进行定长,定格式,一次就发一串报文接受也一样,需要对数据序列化与反序列化。而对于UDP这都是不需要做的,发多少,就收多少。

UDP的缓冲区

在编写UDP套接字的时候,我们基本就了解到在发送消息和接收消息的时候,我们貌似只用了一个缓冲区,既可以读,也可以写,我们称为全双工。

实际上UDP并没有真正意义上的发送缓冲区,在调用sendto时会直接交给给内核,由内核将数据传给网络协议进行后续的传输。

但UDP具有接收缓冲区,但是并不保证接受报和发送报的数据顺序是否一致,且缓冲区满了数据就会被丢弃。

注意事项:

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

  基于UDP的应用层协议

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

 TCP协议

相对于UDP协议,TCP协议就更加的重要了,TCP---传输控制协议面积对数据传输会做详细的控制,对于数据什么时候发,发多少,发错了怎么办全由TCP自主决定。

宏观上就是将数据拷贝到的缓冲区,之后交给协议传输,发送方再从缓冲区处拷贝数据,即本质就是数据拷贝。

TCP的报文格式

不同层时,对数据的的描述方式也不一样,对于传输层骂我们一般叫做数据段。

TCP传输面向字节流
报文首部:固定20字节,最长60字节
源端口:2字节
目的端口:2字节
SN:序号,4字节,报文段所发送的第一个字节的序号
ACK:确认号,4字节,期望收到对方下一个报文段的第一个字节的序号
Data Offset:数据偏移,4位,即首部长度,无选项时为0x5
控制位:12位,后五位依次为:ACK,PSH,RST,SYN,FIN
第一次握手:0x02(SYN)
第二次握手:0x12(SYN+ACK)
第三次握手:0x10(ACK)
第一次挥手:0x19(ACK+PSH+FIN)
第二次挥手:0x10(ACK)
第三次挥手:0x19(ACK+PSH+FIN)
第四次挥手:0x10(ACK)
窗口:2字节,发送方的接收窗口大小
校验:2字节
紧急指针:2字节
选项:MSS选项(4字节)
前两次握手时一般需要协商MSS,因此数据偏移和控制位分别为0x6002和0x6012-第三次握手和所有四次挥手一般无选项
三次握手
第一次:ACK1=0(无ACK标志)
第二次:ACK2=SN1+1
第三次:SN3=ACK2=SN1+1,ACK3=SN2+1
四次挥手
第二次:SN2=ACK1,ACK2=SN1+1
第三次:SN3=SN2,ACK3=ACK2
第四次:SN4=ACK3=SN1+1,ACK4=SN3+1

TCP的前20字节为它的标准报头,之后的为数据的有效载荷。 

那么如何对数据的报头和有效载荷进行分离呢:固定长度+自描述字段

第一层是16源端口号与16位目的端口号(32位序号)(32位的确认序号)

序列号与确认字段号都是为了保证数据可靠传输:

 此外还有确认序号,表示确认字段号前的数据我已经接收到了。

至于为什么要有两个序号这是因为:极有可能是确认应答的报文,也有可能时数据加确认报文。

第二层首先是单位大小位4字节的首部长度,之后16位的窗口大小

 先以前两层来看,如果发送发一直向接收方发送数据,因为发送方并不知道接收方的承受能力,所以当缓冲区的数据溢满了,此时就有可能来不及接收数据,(发送方还在发),就会出现数据大面积丢失的情况。为了确保数据发送是安全可靠的,因此需要根据接收方的缓冲区,控制发送数据的速率,这种方式就叫做流量控制。

其次每次发送还需要有确认应答机制保证数据传输。除此之外,如果还存在数据发送后丢包,还会有超时重发机制。综上我们再来看看报文的接收与发送。

所以发送方发送后每一要回收应答,从而确定自己的传输速率(根据接收方接收缓冲区的大小),而这里16位字段存储的就是接收方剩余空间的大小。

6 位标志位 :
URG: 紧急指针是否有效
ACK: 确认号是否有效
PSH: 提示接收端应用程序立刻从 TCP 缓冲区把数据读走
RST: 对方要求重新建立连接 ; 我们把携带 RST 标识的称为 复位报文段(存在二次握手最后发数据,及连接建立不一致(网络问题))
SYN: 请求建立连接 ; 我们把携带 SYN 标识的称为 同步报文段
FIN: 通知对方 , 本端要关闭了

 连接建立是否成功就看能不能收到第三次发送的确报文;链接一旦连接建立好,由于有多个客户端,所以我们还需要对链接进行管理。

综上基本上TCP的包头的字段的主要功能就是这些了。

现在我们再来细看关于TCP的一些确保数据安全传输的机制:

1.ACK确认应答机制

ACK应答机制我们在6个标志位字段已经了解过了,如发送方通过三次握手建立连接中,就是通过设置报文中的ACK字段,表明已确认收到报文,以及在数据的发送过程中。

2.超时重传

 实际上数据在传输的过程,我们并不会知道关心数据是不是丢包了,还是在阻塞者,我们只有当接收方收到才知道传输没问题,但我们怎么去确信数据是丢包了还是阻塞?因此通过设定固定的时间间隔,如果超时(可能阻塞----路由选择的路径太差,可能网络断开丢包了),都会重新传输该报文。

3.TCP的链接管理机制

 刚开始,发送方想要和接收方发送数据前,需要先建立连接,通过三次握手:

发送方先向接收方发送建立连接的请求SYN,接收方接受后发送确认建立连接ACK+SYN,之后发送发收到,发送确认收到建立连接的报文ACK。

之后就进行数据传输。

所以在我们编写套接字的时候,接口connect就是去形成一个建立连接请求的报文,而accept只关心三次握手成功时,返回的文件缓冲区connfd。

最后关闭连接的时候,通过四次挥手关闭连接:想要关闭的一方向接收方发送FIN报文,请求断开连接,接收方接收到后发送确认收到ACK,之后在向对方发送取消l连接的报文FIN,之后发送方再次发送ACK确认收到保文,并将自己的状态为立马ime_wait。套接字就是通过closed发送FIN报文。

链接有全连接对列,也有半连接对列--被建立连接的一方(维护的时间不长)。listen接口的第二个参数代表全链接队列的长度+1。

为什么全连接队列不能长呢--当上层很忙的时候,下层还不断有新的连接,那么没时间去处理对列,那么就会白白占用资源。

为什么要三次握手呢?

实际上真的是三次握手吗?发送方先发送SYN建立连接,接收方接受到后向对方发送ACK,之后再次向发送方发送建立链接的请求,只不过在发送时,我们将这两条报文合二为一了,即ACK+SYN

(应答时附带建立SYN报文),之后收到再次发送ACK,确认建立。

看到这里我们发现,其实四次挥手也可以压缩为三次挥手。

至于为什么不压缩,对于连接时,SYN与ACK不存在时间差,你给我发,我就跟你建立连接。但是在挥手时,你给我说再见,我不会直接就跟你说再见,我指挥先收到你的再见,根据情况,在看是否真的就和你说再见。

1.建立三次握手有一点就是 验证全双工通道是否流畅。

2.如果只有一次握手,存在SYN泛洪攻击,一直发建立连接,服务端需要资源来接受,就存在连接资源被打满的情况,如果是两次握手,发送方先发送给服务端,服务端先建立连接后发送报文给客户端,此时客户端才建立连接,这还是会存在客户端出现异常导致服务端在建立连接消耗资源。

只要出现影响,后果全让服务端来承受,因为客户端的基数大。

但当三次握手时,我们能知道给你发送的确认,你是否收到,报文是否丢失。

理解TIME_WAIT状态

现在做一个测试 , 首先启动 server, 然后启动 client, 然后用 Ctrl-C 使 server 终止 , 这时马上再运行 server, 结果是 :
这是因为,虽然server的应用程序终止了,但TCP协议层的连接并没有完全断开,因此不能再次监 听同样的server端口.
我们用netstat命令查看一下:
TCP协议规定,主动关闭连接的一方要处于TIME_ WAIT状态,等待两个MSL(maximum segment lifetime) 的时间后才能回到CLOSED状态.
我们使用Ctrl-C终止了server, 所以server是主动关闭连接的一方, 在TIME_WAIT期间仍然不能再次监听。
同样的server端口;
MSL在RFC1122中规定为两分钟,但是各操作系统的实现不同, 在Centos7上默认配置的值是60s;
可以通过 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看msl的值;
那如何解决这个问题呢?
使用setsockopt()设置socket描述符的 选项SO_REUSEADDR为1, 表示允许创建端口号相同但IP地址不同的多个 socket描述符。

 那么为什么断开的时候,断开的一方需要等待呢?

1.让通信双方的历史数据消散。

2.让我们断开连接,四次挥手有较好的容错性。

 流量控制(可靠性+效率)

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送,就会造成丢包, 继而引起丢包重传等等一系列连锁反应. 
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);
接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 "窗口大小" 字段, 通过ACK端通知发送端;
窗口大小字段越大, 说明网络的吞吐量越高;
接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
发送端接受到这个窗口之后, 就会减慢自己的发送速度;
如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端

在超时重传的时候,首先会想接收方发送一个窗口检测,判断双方是否能通信,如果你发不了,我收不到,那大概率就是网络的问题了,此时就断开链接了。

滑动窗口

我们已经了解到了确认应答机制是为了保证数据的可靠性,发送一次数据包,收到后就要向我发送ACK,没发一次,对应就要发ACK,如果距离太远,那么数据传输的效率就比较低了。

因此在实际发送数据时,发送方会将发送的数据进行分批次发出去,接收方接受这些请求再一个个发送确认报文,由于某些问题,接收方接受了,但没发送确认,根据超时传输再次发送,此时还没发送确认的数据就还是会保存到缓冲区当中,所以需要对缓冲区进行分区,这里我们简单的分区:

对于发送缓冲区:

发送滑动窗口的大小一般为接收方的窗口的大小。一般使用双指针对区域进行划分,如果区域需要扩大或者缩小,指针就可以向前或者向后滑动--因此被称为滑动窗口。

在该窗口内的报文,可以立即发送,可以不需要收到应答。

但是如果存在滑动窗口中间丢包怎么办?如果不是头一个ACK丢失,即使丢包了,滑动窗口也能确认丢包之后的ACK,因为存在确认序号。即使丢了,也能向后继续更新。

所以每次都是尽快的将数据从内核拿出来, 腾出更大的缓冲区,这样窗口也就大了。

拥塞控制

虽然 TCP 有了滑动窗口这个大杀器 , 能够高效可靠的发送大量的数据 . 但是如果在刚开始阶段就发送大量的数据 , 仍 然可能引发问题:
因为网络上有很多的计算机 , 可能当前的网络状态就已经比较拥堵 . 在不清楚当前网络状态下 , 贸然发送大量的数据 , 是很有可能引起雪上加霜的. TCP引入
慢启动 机制 , 先发少量的数据 , 探探路 , 摸清当前的网络拥堵状态 , 再决定按照多大的速度传输数据 ;

TCP的特点

与UDP相比,TCP具有发送缓冲区,在将数据拷贝至发送缓冲区时,会有tcp下层协议决定,之后接收方从接收缓冲古拷贝数据。总结就是TCP是一个由接受和发送缓冲区的,全双工的,数据发送控制的一个协议。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习中的注意力机制二(Pytorch 16)

一 Bahdanau 注意力 通过设计一个 基于两个循环神经网络的编码器‐解码器架构,用于序列到序列学习。具体来说,循环神经网络编码器将长度可变的序列转换为固定形状的上下文变量,然后循环神经网络 解码器根据生成的词元和上下文变量按词元生成…

【iOS】KVO

文章目录 前言一、KVO使用1.基本使用2.context使用3.移除KVO通知的必要性4.KVO观察可变数组 二、代码调试探索1.KVO对属性观察2.中间类3.中间类的方法3.dealloc中移除观察者后,isa指向是谁,以及中间类是否会销毁?总结 三、KVO本质GNUStep窥探…

IDEA基于Maven构建项目

IDEA基于Maven构建项目 一、Maven简介 Apache Maven 是一个软件项目管理和理解工具。基于项目对象模型的概念(POM),Maven 可以从中心信息中管理项目的构建、报告和文档。 Apache Maven 可以用于构建和管理任何基于 Java 的项目。 下载地址…

EPAI手绘建模APP颜色、贴图、材质、样式

⑦ 颜色选择页面 1) 颜色环选色。 图 65 颜色选择器-颜色环 2) RGB选色。 图 66 颜色选择器-RGB 3) HSL选色。 图 67 颜色选择器-HSL 4) 国风颜色库选色。 图 68 颜色选择器-国风 5) CSS颜色库选色。 图 69 颜色选择器-CSS 6) 历史颜色:保存最近使用的多个颜色&…

OpenCV如何使用 GDAL 读取地理空间栅格文件(72)

返回:OpenCV系列文章目录(持续更新中......) 上一篇:OpenCV的周期性噪声去除滤波器(70) 下一篇 :OpenCV系列文章目录(持续更新中......) 目录 目标 代码: 解释: 如何使用 GDAL 读取栅格数据 注意 …

ElasticSearch自动补全

一、拼音分词器: 当用户在搜索框输入字符时,我们应该提示出与该字符有关的搜索项,如图: 这种根据用户输入的字母,提示完整词条的功能,就是自动补全了。 GET /_analyze {"text":"我爱螺蛳粉…

.Net MAUI 搭建Android 开发环境

一、 安装最新版本 VS 2022 安装时候选择上 .Net MAUI 跨平台开发 二、安装成功后,创建 .Net MAUI 应用 三、使用 VS 自带的 Android SDK 下载 ,Android镜像、编译工具、加速工具 四、使用Vs 自带的 Android Avd 创建虚拟机 五、使用 Android 手机真机调试

【小菜鸟之---Ansible基础详解】

文章目录 1 【Ansible简介】1.1简介1.2 Ansible 特点1.3 Ansible的工作机制1.4Ansible任务工作模式 2【安装部署】2.1安装命令2.2 Ansible配置文件2.3主机清单配置2.4 基于ssh免密登录2.5常用命令 3【Ansible常用模块】3.1 ping模块3.2 shell模块3.3 command模块3.4 copy模块3.…

百度下拉框负面信息如何删除?

百度头条360等搜索引擎,作为人们获取信息的主要途径之一。然而,一些知名的企业或个人可能会面临在搜索的下拉框中出现负面信息的问题,这可能对其声誉和形象造成不良影响。小马识途营销顾问根据自身从业经验,针对这类情况提出以下建…

一、写给Android开发者之harmony入门

一、创建新项目 对比 android-studio:ability类似安卓activity ability分为两种类型(Stage模型) UIAbility和Extensionability(提供系统服务和后台任务) 启动模式 1、 singleton启动模式:单例 2、 multiton启动模式&#xff1…

【软件测试理论002】认识软件缺陷、缺陷生命周期、缺陷分类

目录 1 认识软件缺陷 1.1 什么是软件缺陷 1.2 缺陷存在哪些方面 1.3 软件缺陷示例 1.4 软件缺陷的表现形式 1.5 软件缺陷产生的原因 1.6 软件缺陷的根源 1.7 软件缺陷修复的费用 2 软件缺陷的信息分类 2.1 软件缺陷的生命周期 2.2 软件缺陷的信息 2.3 软件缺陷分类…

Node.js -- mongoose

文章目录 1. 介绍2. mongoose 连接数据库3. 插入文件4. 字段类型5. 字段值验证6. 文档处理6.1 删除文档6.2 更新文档6.3 读取文档 7. 条件控制8. 个性化读取9. 代码模块化 1. 介绍 Mongoose是一个对象文档模型库,官网http://www.mongoosejs.net/ 方便使用代码操作mo…

CNN实现卫星图像分类(tensorflow)

使用的数据集卫星图像有两类,airplane和lake,每个类别样本量各700张,大小为256*256,RGB三通道彩色卫星影像。搭建深度卷积神经网络,实现卫星影像二分类。 数据链接百度网盘地址,提取码: cq47 1、查看tenso…

Rust Rocket创建第一个hello world的Web程序 Rust Rocket开发常用网址和Rust常用命令

一、Rust Rocket简介 Rust Rocket 是一个用 Rust 语言编写的 Web 应用框架,它结合了 Rust 的安全性和性能优势,以及 Web 开发的便利性。以下是 Rust Rocket 框架的一些优点: 安全性:Rust 是一种注重安全性的编程语言,…

Redis-分片机制

概述 业务需要:由于单台redis内存容量是有限的,无法实现海量的数据实现缓存存储 概念:由多个redis节点协助工作的机制就是redis的分片机制 作用:为了实现redis扩容 特点:分片机制把该机制中包含的多台redis缓存服务…

PostgreSQL和openGauss优化器对一个关联查询的SQL优化改写

PostgreSQL和openGauss数据库优化器在merge join关联查询的SQL优化改写 PostgreSQL 查询计划openGauss 查询计划拓展对比 看腻了文章就来听听视频讲解吧:https://www.bilibili.com/video/BV1oH4y137P7/ 数据库类型数据库版本PostgreSQL16.2openGauss6.0 创建测试表…

【Android】Android应用性能优化总结

AndroidApp应用性能优化总结 最近大半年的时间里,大部分投在了某国内新能源汽车的某款AndroidApp开发上。 由于该App是该款车上,常用重点应用。所以车厂对应用性能的要求比较高。 主要包括: 应用冷启动达到***ms。应用热(温)启动达到***ms应…

C语言 | Leetcode C语言题解之第70题爬楼梯

题目: 题解: int climbStairs(int n) {double sqrt5 sqrt(5);double fibn pow((1 sqrt5) / 2, n 1) - pow((1 - sqrt5) / 2, n 1);return (int) round(fibn / sqrt5); }

Vue通过下拉框选择字典值,并将对应的label以及value值提交到后端

产品品种从字典中获取 产品性质也是从字典中获取 字典当中的保存 dict_type表 dict_data表 在表单提交的方法中 1.因为做的产品性质是多选,它会以数组的方式提交,所以需要先将Json格式转变为String JSON.stringify(this.form.nature) 2.提交表单&…

Java基于Spring Boot框架的课程管理系统(附源码,说明文档)

博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&#x1f3…