| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 计算机网络之UDP与TCP协议(三次握手 四次挥手) -> 正文阅读 |
|
[网络协议]计算机网络之UDP与TCP协议(三次握手 四次挥手) |
??前面的话?? 本文介绍计算机网络中有关传输层协议的知识——UDP与TCP协议,在TCP协议中,为了保证数据的可靠传输,引入了十大保证可靠性的机制,即确认应答,超时重传,连接管理(三次握手,四次挥手),滑动窗口,流量控制,拥塞控制,延时应答,捎带应答,粘包问题,TCP异常处理,这些都是UDP所不具备的,因为UDP不能保证数据的可靠性。
📌导航小助手📌🍋1.UDP协议UDP是User Datagram Protocol的缩写,该协议不需要连接,不稳定传输,面向数据报,全双工,简单且高效,但是它的数据载荷较小,一般适用于以下场景:
UDP协议的格式: 源端口号(2字节):发送方的端口号。 🍋2.TCP协议🍒2.1TCP协议结构TCP协议相比于UDP协议要复杂一些,TCP需要连接,传输是可靠的,面向字节流,全双工。 TCP协议格式: 数据偏移,表示TCP数据起始处与TCP报文起始处之间的距离,其实就是TCP首部报头长度了,一共4比特,能表示0-15,单位为4字节,也就是说能表示TCP报头长度为0-60字节,基本上完全够用了,就算有一天不够用了,数据偏移后面还有6比特备用。 选项可有可无也可以有多个,可能包括“窗口扩大因子”、“时间戳”等选项。长度可变,最长可达 40 字节,当没有使用选项时,TCP 首部长度是 20 字节。填充是为了保证选项为32比特的整数倍。 控制位,字段长为8比特,每一位从左至右分别为CWR、ECE、URG、ACK、PSH、RST、SYN、FIN。
TCP数据段是可变的,可以简单的理解数据载荷没有限制。 其他的我们慢慢细说,我们知道TCP是稳定传输,具体说是在保证稳定的情况下尽可能地去提高传输效率,可以从以下十个方面来解释TCP是如何保证稳定传输以及尽可能提高效率的。 🍒2.2TCP可靠性实现机制🍇2.2.1确认应答保证数据可靠传输的第一关就是确认应答,我们知道可靠性的核心就是发送方知道发送数据有没有被接收方收到,确认应答机制是实现可靠性的核心机制。 确认应答的关键就是发送方发送数据给接收方后,接收方会自动返回一个响应表示收到数据了。 比如,你和你的女神聊天说要请她吃火锅,当你看到她的回复的时候,你就知道消息她收到了。 其中B给A回复的确认应答报文也被称为ACK,但是现实毕竟是现实,理想是理想,总会有意外,比如网络原因可能会导致发送数据或者ACK丢包了,丢包了怎么办?那只能重新传一个新的数据包呗,所以就有了下面的超时重传机制。 🍇2.2.2超时重传超时重传是确认应答机制的一个补充,当出现丢包等情况时,超时重传就要“上阵”了。 当一个数据发送后,一定时间段内,没有收到确认应答,就会进行重发,当然重发不是无限制的,重发一定次数后就会降频重发或者就不会再重发了,因为在网络正常的情况下丢包的概率是很小的,两次以及多次丢包的概率那就更加小了。 超时重传机制运行图: 🍇2.2.3连接管理(三次握手,四次挥手)对于TCP是需要建立连接的,所以就有了连接管理机制,其实也是保证可靠性的一种机制。对于TCP的连接管理就是三次握手,四次挥手。 客户端与服务器之间进行三次交互建立连接的过程被形象地称为“三次握手”。 在建立三次握手的过程中,服务器与客户端的状态不断在改变,三次握手更加详细的图如下:
三次握手的作用不限于建立连接,除此之外三次握手还能检测发送能力与接收能力是否正常。 既然有连接,那么自然会有断开连接的时候,客户端与服务器通过四次交互而断开连接的过程被称为“四次挥手”。 首先,客户端发出断开连接FIN请求,然后服务器收到请求后立即响应ACK(内核返回ACK),服务器调用 同理,四次挥手过程中客户端与服务器的状态也在发生改变,我们来了解一下这些状态。 上图的主动方是客户端,被动方是服务器。
由于最后一次主动方发送ACK后可能存在丢包,如果丢包了,被动方就会以最坏情况认为自己的FIN丢了,会重发FIN,所以主动方需要等待被动方重发FIN,因此预留了一段时间用来等待被动方FIN重传,等待时间是2MSL,MSL表示报文最大生存时间,也就是在网络传输过程中的最大传输时间。如果等待过程中没有接收到FIN,服务器与客户端就断开连接了。 虽然可靠性是TCP最高机制,但是TCP会在可靠性保证的情况下尽量提升传输速度,所以为了在稳定性的基础上提升性能,引出了滑动窗口等机制。 🍇2.2.4滑动窗口滑动窗口在保证传输的可靠性的前提下,尽量地提高传输效率。 我们不难发现,由于确认应答机制的存在,导致每执行一次发送操作,都需要等待ACK的到达,大部分的时间都用在等ACK上了。 这就相当于一个大小为4的窗口滑动,原来数据的范围是1-4000,收到一个1001确认应答响应后,数据的范围就变成了1001-5000,相当于窗口向右滑动了一格。 但是上面的是正常的情况,也就是没有考虑后发先制和丢包的情况,下面我们来讨论一下这几种情况, 情况1:后发先制,当出现1001-2000比1-1000先到达这种情况时,由于确认应答机制,收到1001-2000后,服务器会认为2001之前的数据已经全部到达了,因此会返回确认应答2001,客户端收到2001后,窗口会向右移动两格,传输的数据范围为3001-7000,只要1-1000的数据没有丢,没有任何影响,所以后发先制的情况,不用处理,数据仍然能够正常传输。 情况2:ACK丢了,这种情况其实与后发先制相似,比如1001丢了,当客户端收到2001时发送窗口就会右移两格,数据还是能够正常传输的,只要大部分的ACK没有丢,客户端可以通过下一次或者后面的确认应答序号来进行确认,所以ACK丢了不要紧,该情况也不用处理。
🍇2.2.5流量控制流量控制的关键就是得到处理方的处理速度,然后根据处理方的处理速度来动态调节发送的速度。 而此处是通过接收方缓冲区的剩余容量来衡量接收方处理速度的,发送方发送数据后会放到一个缓冲区,然后接收方通过这个缓冲区来读取数据,这样的一个过程也可以理解为生产者消费者模型,即发送方是生产者,接收方缓冲区是“交易场所”,发送方是消费者,当生产者的生产速度与消费者的消费速度到达平衡时,传输的数据既快又稳定。 不妨把这个接收方的缓冲区看作成一个水池,那么发送方的工作就是注水,接收方的工作就是使用水池中的水,当水位比较低(剩余空间大)那就注水的时候就快一点,水位比较高(剩余空间小)那就注水的时候就慢一点。 当发送方的数据到达接收方的时候,接收方都会返回一个ACK,这个ACK除了确认能够确认应答,还能告知接收方缓冲区的空间还剩余多少,然后发送方根据接收方缓冲区剩余的容量来控制发送速度(窗口大小),当接送方得知接收方缓冲区空间满了的时候,就不会去发送 数据,而是会去发送一个探测窗口报文,获取接收方缓冲区剩余空间的大小。 而上面的获取接收方缓冲区剩余空间大小,是通过TCP报头中的窗口大小来进行获取,占据16位(即64k),实际上这里的可描述的窗口大小不止64k,因为TCP报头选项中还包含选项,选项里面有一个窗口扩大因子M,实际窗口大小是将窗口大小字段左移M位,也就是扩大 2 M 2^M 2M倍。
🍇2.2.6拥塞控制拥塞控制是滑动窗口的延伸,也就是限制滑动窗口中数据的发送速度,拥塞控制描述的是从接收方到发送方之间链路的拥堵情况。 发送方发送的多快不仅取决于接收方的处理能力,还取决于中间链路的处理能力。而发送方与接收方中间的结点的个数我们是不得而知的,因此拥塞控制采取“测试实验”的方式来逐渐调整发送的速度。 一开始的时候接收方会以较小的窗口进行发送,通过逐渐提高窗口的大小,当窗口达到一定的大小,就会出现丢包的情况,这就意味着链路就出现了“拥堵”,这时候就会减小窗口的大小,是快速的减小窗口大小,因为如果出现丢包减小窗口大小的速度不够大,可能会出现持续性的丢包,对网络通信的质量会造成很大的影响。 关于拥塞窗口说明如下图: 🍇2.2.7延时应答延时应答,相当于流量控制的延伸,流量控制的目的是为了使发送方不要发送太快,而延时应答在此基础上,想让窗口的大小尽量大一点。 就是发送方询问接收方窗口大小时,不立即做出回答,而是稍等一下在回答,比如一个水池,如果立即回答,回应的剩余空间是20吨,但如果等一下再应答,可能回应的剩余空间是28吨(因为接收方是一直在处理数据的),这样就能使窗口的大小尽量大一点。 🍇2.2.8捎带应答捎带应答是延迟应答的延伸,由于延时应答的存在,ACK并不是立即就发送响应的,当应用层代码需要响应时机与ACK响应时机重合时,就会将这两个数据合二为一,这就是捎带应答。 🍇2.2.9粘包问题粘包问题,就是应用层去取缓冲区的数据时,会出现分不清哪些数据是哪些TCP数据包里面的应用层数据,那也很可能就不知道从哪里到哪里是一个完整的应用层数据报·,就造成了粘包问题,其实不止TCP传输存在这种问题,所有面向字节流读文件都会有这种问题。 那么要怎么解决呢?由于是找不到应用层的数据始末,所以去TCP上面做功夫是不可行的,问题出在哪里,就要在哪里解决,毕竟解铃还须系铃人。所以解决办法就是在应用层协议中加上包与包之间的边界,比如在应用层数据报结尾加上一个 🍇2.2.10TCP异常处理进行TCP协议传输时会出现以下几种情况: 进程终止: 在进程毫无准备的情况下,突然结束进程,偷袭它,其实它有闪,会偷袭失败。 我们知道TCP连接是通过socket来进行连接的,socket本质上是进程打开的一个文件,文件就存在与PCBZ中的文件描述符表之中,每次打开一个socket文件都会在文件描述表中添加一项,删除会减少一项。 当你强制结束进程时,PCB没了,里面的文件描述符表也没有了,就相当于文件自动关闭了,这个过程和手动调用socket.close方法没有区别,依然会执行四次挥手过程。 机器关机: 机器关机和进程终止是一样的,首先会将PCB全部杀死,然后再进行关机,四次挥手依然会进行。 当电源或网络直接断开时,端电时没有任何时间留给操作系统去反应,所以根本来不及去四次挥手,断网数据都发不出去,那四次挥手也无法成功。 当客户端断电或断网时,服务器就会尝试重新建立连接,,重连失败一定次数,就会放弃连接。 总结一下,UDP与TCP之间的比较,UDP的传输效率高于TCP,但传输的文件较小和对可靠性要求不高时优先使用UDP。TCP是在保证可靠性的前提下,尽可能地去提升效率,但是还是有效率牺牲的,所以TCP的传输效率不如UDP,但是可靠性优于UDP。那么如何基于UDP实现可靠性?这个问题实际上在问你TCP,将TCP可靠性实现的思路在应用层复刻就可以了。当然传输层的协议不只有UDP与TCP,其他的如QUIC,游戏中经常使用。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 2:34:04- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |