【网络面试(5)】收发数据及断开服务器(四次挥手)

 前面了解到服务器和客户端在创建套接字,建立连接后,就可以进入到下一步,双发可以互相发送和接收数据,本篇博客就来学习一下这个过程。
 我们印象里,发送数据应该是我们在浏览器输入网址,敲击回车的一瞬间,发送动作就完成了,回头服务器处理完成将数据发送客户端,浏览器解析出来,这就是反过来接收的过程。

1. 发送数据

 由浅入深,了解这个大体过程,我们先来看看发送数据的简单过程。对于浏览器,他没有办法直接向网络中发送数据,而是要将http请求委托给协议栈(操作系统的网络控制软件)来发送。但实际上,在计算机中,并不是只有浏览器会发送网络请求,QQ、微信等很多应用程序都会执行这个动作。所以协议栈工作就是会接收各种应用程序发送过来的网络请求数据,其实就是一堆的二进制字节数据。

 协议栈在拿到数据后,是不是会直接发送到网络中的呢?必然不是,他在内部会维护一段内存缓冲区,等待下一段数据,然后在某个合适的时机再发送出去。这块内存就是发送数据的专用缓冲区。当然,接收数据的时候也是有一块专用内存的,后面我们再说这个。这里还提到了,合适的时机发送数据,这个时机是根据两个要素来判断的,我们看看是哪两个。

1.1 网络包长度

 第一个因素是跟网络包长度相关的,什么意思呢,对于某些GET请求,要发送的请求内容必然很少,一个网络包就能放得下,但是有些POST请求,比如我要写的这篇博客,经过编码解析,需要很多歌网络包才能放的下,这里就涉及到拆包的概念。

 这里先了解两个网络词汇:MTUMSS

  • MTU: 指的是一个网络包的最大长度,以太网中通常是1500个字节。
  • MSS: MTU中去掉头部之后,所能容纳的数据的最大长度。

在这里插入图片描述

 了解这两个概念,我们在来看下上面说的拆包的概念,即我们发送的某次网络请求,可能是通过1个网络包发送给服务器的,也可能是很多个,决定因素就是MTU和MSS。

 在应用程序将数据发送给协议栈的时候,数据可大可小,协议栈无法决定,如果每次接收到应用程序的一次数据就立即发送出去,必然会导致发送大量小的网络包,网络效率下降。所以,协议栈一般会累积到数据量可以塞满一个网络包的时候再发送出去,即MTU的长度,这就是第一个决定协议栈发送数据的因素。

1.2 发送时间

 决定协议栈 发送数据的第二个因素是时间,为啥呢?我们可以试想一下,如果GET请求的数据长度无法达到一个MTU的长度,协议栈一直等待到一个网络包的数据长度再发出去,必然会产生很大的延迟,给我们卡顿的感觉。所以,某些情况下,即便网络包没有被填满,也会立即把数据发送出去。
 协议栈内部会维护一个计时器,在超过设定的时间阈值后,即便没有达到一个完整网络包数据长度,也会立即发送。一般,这个时间是由协议栈的开发者决定的,不同操作系统的不同版本会有不同实现。

 其实,决定协议栈发送数据的这两个要素,在某些情况下是比较矛盾的,立即发送会导致网络效率下降,等待太久又会造成延迟。过分依靠协议栈来决定发送时机会带来一些问题,所以协议栈也给了应用程序一个选项,来决定是否立即发送。像浏览器这样的会话型应用程序,一般会选择“立即发送”的选项。

2. 确认发送成功以及重发功能的实现

 TCP协议的非常重要的功能就是可以确认通信的一方是否已经成功收到了网络包,如果没有收到,必须具有重发的功能。这个功能的实现就是借助于ACK号和seq序号要进行对方接收确认的操作。

 上文我们说过,在网络请求内容过大的时候,TCP会有拆包的逻辑,那么在拆分的过程中,TCP就会计算好并记录每个网络小包在整个请求内容中处于第几个字节,然后再发送网络包的时候,在TCP头部记录这个字节数(就是seq序号,比如目前是第1个字节),服务器在接收到网络包的时候,会读取这个字节,然后再计算这个网络包MSS的长度(比如网络包数据长度是1000),在确认回复的时候,会将ACK赋值为ACK = 1 + 1000 并返回给客户端。客户端在接收到ACK号的时候就可以确定网络包已经顺利被对方接收,否则就会重试发送。

 我们可以想象一下,客户端在发送下一个网络包的时候,一定是从第1001个字节开始的,于是服务器在收到请求后,可以顺便验证1001是不是和自己最后一次ACK响应的字节数相等,如果相等说明中间没有丢包,如果是2001,说明中间丢失了至少一个网络包。

 这里我们已经提到了ACK和seq,TCP协议可以通过ACK号和序号就可以确认对方是否收到了网络包。我们来看一个虚拟的例子加深一下了解。

在这里插入图片描述

2.1 调整ACK号等待时间

 我们的网络传输并不是一帆风顺的,发生拥塞和抖动的情况是非常常见的。前文我们提到TCP会通过ACK号确认对方已经接收到网络包,但是在网络比较慢的情况下,发送和接收ACK号的平均响应时间就会比较长了,如果客户端在这个时候设置了比较短的等待时间,就会在没收到ACK的情况一直向以太网中发送数据,这对于本来已经繁忙的网络就更加糟糕了,这其实就是TCP的网络包重传。

 通常,当网络包重传发生后,有可能前一个相同网络包的ACK号才返回,这样的重传其实是不必要的。所以,对于等待时间来说,需要设置一个合适的值,这个时间应该是可以动态调整的,而计算方法就是根据过往发送数据的过程中,持续监测ACK号的响应时间,如果ACK号的返回时间变慢,就会响应延长这个等待时间,否则就缩短等待时间。

 除此之外,TCP还是使用了滑动窗口的方式来管理数据发送和ACK号的管理,大体思路就是第一个网络包在发送出去之后,并不是等待当前网络包的ACK号返回才发送下一个,而是直接发送下一个,或者说是下面一系列的网络包,这样的话,发送的等待时间就会被有效的利用起来了。这个过程相对复杂一些,涉及到窗口大小的概念,这个窗口大小就是指接收方网络协议栈中,在当前时间里,剩余的最大缓存空间,也就是能接收的字节数。下图中可以看出来一来一回和滑动窗口的方式,这里不再深入展开,可以查看相关资料。

在这里插入图片描述

3. 接收数据

 在客户端发送完数据的过程后,服务器端就可以接收并处理网络包了,对于单个网络包的处理比较简单,对于客户端拆分后分多次发送的网络包,服务器的TCP协议同样会以相同的方式拼接起来转换成为对应的网络请求,其实就是和客户端处理相反的方式进行的。服务器在处理请求后,就会将相应数据发送给客户端。

 我们可以想一下,客户端的浏览器程序在委托协议栈发送了网络请求后,就处于等待响应结果的状态。这个状态其实是浏览器调用了Socket组件库的read()函数,协议栈会将这个工作挂起,直到服务器数据相应之后,协议栈写入到接收缓冲区中,在这个过程之前,接收缓冲区一直是空的,浏览器就无法处理数据,这个挂起就是我们常说的阻塞过程。这个如果继续延伸的话,会有阻塞式IO,非阻塞式IO,IO多路复用等知识点,在此不深入。

 总结一下这个过程,客户端的协议栈会检查接收到的数据和TCP头部的内容,判断是否有数据丢失,如果没有问题会向服务器返回ACK号。然后协议栈将接收到的数据暂存到接收缓冲区(这个缓冲区是协议栈的)中,然后将数据块按照顺序连接起来还原成原始的数据,最后将数据交还给应用程序,其实是把协议栈缓冲区中的数据复制到浏览器制定的内存地址中,然后浏览器去解析的过程(这个过程还是在read里面实现并把控制流程交还给浏览器的)。

4. 断开连接

 接下来最后一个流程,就是数据发送完成之后的断开连接了,那么断开连接这个操作是由客户端还是服务端发起的呢?
 在协议栈中并没有规定哪一方应该先发起断开操作,通常是由应用程序判断自己的数据已经发起后就可以发起断开动作了。比如我们访问web服务器,发送请求,服务器接受请求处理完成会向客户端返回数据包,等到所有数据都返回了,服务器会主动发起断开操作。下面,我们就以这个例子,服务器先发起断开操作理解这个过程。

 所谓的断开操作也是由发起方调用Socket库的中close()程序实现的,在这个方法中,协议栈会生成包含了断开控制信息的TCP头部,具体来说就是将FIN比特位设置1,然后再委托IP模块将数据发给客户端,接下来,服务器套接字中就会记录下断开操作的相关信息。

 接下来看我们的客户端,在接收到FIN比特位为1的包时,客户端知道了,噢服务器要断开连接了,那好在自己的套接字中标记一下要进入断开操作了,记住这里只是标记一下,同时必须要返回服务器ACK号,告知服务器已收到FIN=1的断开网络包了。

 然后,待到客户端协议栈接收缓冲区数据被应用程序全部取走之后(前面讲到的应用程序的read()操作),客户端感觉时机成熟了,也会向服务器发送一个包含FIN=1头部的网络包,服务器同理也要返回ACK包,至此,双方的通讯正式结束。

在这里插入图片描述

5. 删除套接字

 接下来断开操作的最后一步就是删除套接字,这里尤其注意用来通讯的套接字不会立即删除,而是会等待一段时间后再删除,具体原因如下:

 我们现在举个跟上面相反的断开的例子,由客户端发起断开请求:

  • 客户端发送FIN=1
  • 服务器返回ACK
  • 服务器发送FIN=1
  • 客户端返回ACK

 这里特别注意最后一步,客户端在返回ACK号之后,如果立即删除套接字会发生什么呢?正常情况,可能是服务器收到客户端的ACK号双方通讯结束没问题。但是如果因为网络拥塞问题,服务器没有在规定时间收到第四步的ACK号,那么服务器又发送了一次FIN=1,这里可能会有问题了,因为客户端已经删除了套接字,此时如果恰巧又其他应用程序请求连接服务器并且创建了相同端口号的套接字,那么这个新创建的套接字因为收到了一条莫名奇妙的FIN=1就要进入断开操作了,就会有问题了。所以客户端并不会立即删除套接字,就是为了防止这个问题发生。
 通常,这个等待删除套接字的时间就是几分钟而已。

6. TCP的整体流程

在这里插入图片描述

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

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

相关文章

【Python】ubuntu python>3.9编译安装,及多个Python版本并存的使用方法

【Python】ubuntu python3.9编译安装,及多个Python版本并存的使用方法 1. 安装依赖2. 编译与安装2.1 依赖与源获取2.2 配置2.3 编译2.4 安装2.5 建立软连接 链接动态库 3. 多版本兼容 1. 安装依赖 更新系统软件 在正式开始之前,建议首先检查系统软件是否…

FairGuard游戏加固产品常见问题解答

针对日常对接中,各位用户对FairGuard游戏加固方案在安全性、稳定性、易用性、接入流程等方面的关注,我们梳理了相关问题与解答,希望可以让您对产品有一个初步的认知与认可。 Q1:FairGuard游戏加固产品都有哪些功能? A:FairGuar…

VSCode + vite + vue3断点调试配置

没想到这个配置我搞了一上午,网上很多的配置方案都没有效果。总算搞定了,特此记录一下。 首先需要在.vscode文件夹下面创建launch.json配置文件。然后输入如下配置: {// 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。//…

【AIGC-图片生成视频系列-5】I2V-Adapter:一种用于视频扩散模型的通用图像生成视频适配器

目录 一. 项目与贡献概述 二. 方法详解 a. 整体框架图 b. 帧相似性先验 三. 一般化图像生成动画结果 四. 基于个性化 T2I 模型的动画结果 五. 结合ControlNet动画结果 六. 项目论文和代码 七. 个人思考与总结 在快速发展的数字内容生成领域,焦点已从文本到…

思福迪运维安全管理系统 test_qrcode_b RCE漏洞复现

产品简介 思福迪运维安全管理系统是思福迪开发的一款运维安全管理堡垒机 漏洞描述 由于思福迪运维安全管理系统 test_qrcode_b路由存在命令执行漏洞,攻击者可通过该漏洞在服务器端任意执行代码,写入后门,获取服务器权限,进而控…

利用Pandas进行高效网络数据获取

利用Pandas进行高效网络数据获取 背景: ​ 最近看到一篇关于使用Pandas模块进行爬虫的文章,觉得很有趣,这里为大家详细说明。 基础铺垫: ​ pd.read_html pandas 库中的一个函数,用于从 HTML 页面中读取表格数据并…

【G-LAB】郭主任的Linux免费公开课~又要开始啦!

带你一起走进Linux的世界! 【G-LAB】 Linux最新技术—免费公开课即将开讲! 无论是想学习红帽RHEL9.0新特性还是Ansible、容器相关内容, 这个公开课都是你不容错过的! ** 公开课课程为期两天,1月4日&1月…

单片机开发--keil5

一.keil5 Keil uVision5是一个集成开发环境(IDE),用于对嵌入式系统中的微控制器进行编程。它是一个软件套件,包括源代码编辑器、项目经理、调试器以及微控制器开发、调试和编程所需的其他工具。Keil uVision5 IDE主要用于对基于A…

【数据结构】七、图

一、概念 图:记为G(V,E) 有向图:每条边都有方向 无向图:边无方向 完全图:每个顶点都与剩下的所有顶点相连 完全有向图有n(n-1)条边;完全无向图有n(n-1)/2条边 对于完全无向图,第一个节点与剩下n-1个节点…

【CISSP学习笔记】5. 安全架构和工程

该知识领域涉及如下考点,具体内容分布于如下各个子章节: 使用安全设计原理来研究、实施与管理工程过程理解安全模型的基本概念(例如 Biba、Star Model、Bell-LaPadula 等模型)基于系统安全要求选择控制措施理解信息系统 (IS) 的安…

Android ImageView的Bitmap在scaleType情况下Bitmap顶部与底部RectF坐标,Kotlin

Android ImageView的Bitmap在scaleType情况下&#xff0c;Bitmap顶部与底部RectF坐标&#xff0c;Kotlin 通常&#xff0c;在ImageView设置scaleType后&#xff0c;Android会把原始图片通过缩放放在ImageView里面&#xff0c;例如&#xff1a; <ImageViewandroid:id"id…

【Linux操作系统】探秘Linux奥秘:文件系统的管理与使用

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;诗赋清音&#xff1a;柳垂轻絮拂人衣&#xff0c;心随风舞梦飞。 山川湖海皆可涉&#xff0c;勇者征途逐星辉。 目录 &#x1fa90;1 初识Linux OS &…

白话机器学习的数学-2-分类

1、设置问题 图片分类&#xff1a;只根据尺寸把它分类为 纵向图像和横向图像。 如果只用一条线将图中白色的点和黑色的点分开&#xff1a; 这次分类的目的就是找到这条线。 2、内积 找到一条线&#xff0c;这是否意味着我们要像学习回归时那样&#xff0c;求出一次函数的斜率…

大数据背景下基于联邦学习的小微企业信用风险评估研究

摘要&#xff1a; 小微企业信用风险评估难是制约其融资和发展的一个主要障碍。基于大数据的小微企业信用风险评估依然面临着单机构数据片面、跨机构数据共享难、模型不稳定等诸多挑战。针对相关问题和挑战&#xff0c;本项目拟在多主体所有权数据隐私保护与安全共享的背景下&am…

梳理Langchain-Chatchat-UI接口文档

在 Langchain-Chatchat v0.1.17 版本及以前是有前后端分离的 Vue 项目的&#xff0c;但是 v0.2.0 后就没有了。所以本文使用的是 Langchain-Chatchat v0.1.17 版本中的 Vue 项目。经过一番折腾终于将 Langchain-Chatchat v0.1.17 版本前端 Vue 接口和 Langchain-Chatchat v0.2.…

人大金仓数据库与mysql比较

简介 人大金仓数据库是基于 PostgreSQL 开发的。 SQL语言 语法 关键字 KES&#xff1a; MYSQL&#xff1a; 语句 *特性MYSQLKES字符串字面量单引号()或 双引号(")十六进制字面量0x5461626c65&#xff0c;X5461626c65/BIT字面量b1000001,0b1000001/Boolean字面量常…

数据加密、端口管控、行为审计、终端安全、整体方案解决提供商

PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是关于这几个概念的解释&#xff1a; 数据加密&#xff1a;这是一种通过加密算法和密钥将明文转换为密文&#xff0c;以及通过解密算法和解密密钥将密文恢复为明文…

生活常识-如何开社保证明(四川)

下载并打开天府市民云APP 注册后登陆 点击社保服务 点击社保证明 点击【四川省社会保险个人社保证明名(近24个月)】 点击下载 下载后点击【QQ发送给好友&#xff0c;然后发送给自己的电脑设备(我的电脑)】

设计模式之工厂设计模式【创造者模式】

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

国标GB28181对接的时候如何配置服务端口和本地端口

目 录 一、国标GB28181对接需要配置的端口等参数 二、GB28181服务器端口的配置&#xff1a;SIP服务器端口 三、GB28181设备测端口的配置&#xff1a;本地SIP端口 &#xff08;一&#xff09;本地SIP端口配置的意义 &#xff08;二&#xf…