《计算机网络自顶向下方法-第八版》

计算机网络自顶向下方法

  • IO多路复用技术
  • epoll select poll的区别
  • Reactor模式和Proactor模式,阻塞非阻塞,同步异步
  • 浏览器搜索过程
  • 电脑断网排查
  • TCP/IP五层网络模型
  • 网络协议
  • Http & Https
  • HTTP状态码
  • HTTP 常见字段
  • GET 和 POST
  • HTTP1.1
  • HTTP 与 HTTPS
  • 对称加密与非对称加密
  • TLS握手过程
  • HTTP和RPC
  • IP协议
  • DNS 域名解析协议
  • ARP协议
  • NAT
  • DHCP协议
  • TCP
  • TCP和UDP区别
  • 实现一个可靠的UDP传输
  • Cookie和Session
  • 三次握手
  • 四次挥手
  • 1、TCP重传机制
  • 2、滑动窗口
  • 3、流量控制
  • 4、拥塞控制
    • 1、慢启动
    • 2、拥塞避免
    • 3、拥塞发生

IO多路复用技术

  • 通信双方都有一个socket,以一个文件描述符的形式存在,那这个fd也对应了内核当中的一块缓存区,缓冲区里有读缓冲区和写缓冲区,一端写另一端读,IO也就是指这样对缓冲区的操作。多路复用能够让程序同时监听多个文件描述符。

epoll select poll的区别

select/poll/epoll 都是内核提供给用户态的多路复用系统调用
区别:

  1. select和poll要检测的文件描述符集合是在用户态下创建的,每次调用都需要从用户态拷贝到内核中。而epoll从创建开始就是在内核空间创建的。
  2. 判断是否有文件描述符就绪,select和poll需要遍历整个文件描述符的集合,遍历的时间复杂度都是O(n)。而epoll利用了内核的事件驱动机制,只有当文件描述符就绪时才会返回,在硬件的支持下是O(1)的时间复杂度。
  3. select和poll都只能工作在相对低效的LT模式下,而epoll同时支持LT和ET模式。
  • 水平触发:当文件描述符就绪时,它们会一直通知应用程序直到应用程序处理完该事件
  • 边缘触发:它只会通知应用程序一次,所以我们一般会循环的从文件描述符中读写数据,一次性尽可能多的读取数据。
  • 一般来说,边缘触发的效率比水平触发的效率要高,因为边缘触发可以减少系统调用次数,减少开销的。
  • 当监测的fd数量较小,建议使用select和poll;当监听的fd数量较多,使用epoll会明显提升性能。
  • epoll 在内核里使用「红黑树」来关注进程所有待检测的 Socket
    epoll是同步还是异步
    epoll 通常被认为是一种介于传统同步 I/O 和完全异步 I/O 之间的机制。
    同步的:epoll 通过 epoll_wait() 系统调用来通知应用程序哪些文件描述符已经准备就绪,应用程序在接收到通知后就要去执行实际的 I/O 操作。这种模式更接近于同步 I/O。
    异步的:epoll 允许应用程序先注册对特定的 I/O 事件,当这些事件发生之后操作系统会自动通知应用程序。这种机制避免了应用程序需要轮询检查 I/O 状态,这是异步 I/O 的一个关键特征。
    所以总体而言它是同步的,但又提供了一种接近异步 I/O 的编程模型。

Reactor模式和Proactor模式,阻塞非阻塞,同步异步

从数据流的角度串联 Reactor模式和Proactor模式,阻塞非阻塞,同步异步

  • 数据的流向有大致可以分为两个阶段:[1]数据在网络上传输,还没有到达内核缓冲区 -> [2]数据到达内核缓冲区,还没有拷贝到进程缓冲区
  1. 当一个客户端的请求到达,这个请求可能是新的客户端的连接请求,也可能是已连接的客户端的数据请求。
  • 在到达之前什么都不做等待到达才执行,是阻塞。
  • 不等待,而是可以先去执行其他代码,一段时间后再次检查请求到了没有。直到完成才通知CPU过来继续执行,这是一个轮询的思想,这是非阻塞。
  • 阻塞非阻塞发生在数据准备阶段,虽然等待方式不同,但都需要线程主动参与数据准备的过程,都属于同步IO。
  1. 数据已经到达内核缓冲区,需要拷贝到进程缓冲区,这个时候就需要accept和read。此时就有问题,read和accept是工作线程做吗?
  • reactor模式:主线程只负责监听和分发事件,也就是说主线程会通知工作线程来做read和accept,read和accept是个IO过程,就需要工作线程来等待IO时间。这种情况是同步IO
    • Reactor 模式是灵活多变的,在实际项目中reactor可以有多个
    • 多reactor的模式就是一个main reactor对新的连接到达进行监听,其他几个sub reactor对已经建立连接的socket进行监听
  • proactor模式:不需要工作线程来做io,aio_read和aio_accept都是操作系统内核来做的,它做完之后数据读取到了进程空间,这时才唤醒线程池中的工作线程来处理业务逻辑,工作线程不需要浪费任何的IO时间。这就是异步IO
    无论是 Reactor,还是 Proactor,都是一种基于「事件分发」的网络编程模式,区别在于 Reactor 模式是基于「待完成」的 I/O 事件,而 Proactor 模式则是基于「已完成」的 I/O 事件。
    同步异步区别是在,数据就绪之后,接下来的读写操作由谁来读写
    同步表示整个数据的读取过程都是由请求方自己完成的。
    异步表示,请求方通知操作系统去处理读写,它可以去处理其他事情,等待操作系统将这个事件完成后来通知请求方做自己的业务处理

浏览器搜索过程

  • 解析URL:比如需要请求的是什么地方的什么文件。
  • DNS查询获得IP地址
    • 浏览器会先查看自身的缓存
    • 操作系统的缓存
    • host文件
    • 本地域名服务器:本地DNS服务器一般是网络运营商的服务器地址(移动、电信)
    • 根域名服务器
    • 顶级域名服务器
    • 权威域名服务器
  • 生成请求消息:对什么地方的什么文件做什么事情。请求行、请求头、空行、请求体
  • 三次握手建立TCP链接
  • 发送HTTP请求
    • 在发送数据包时,如果目标ip不是本地局域网,那么 MAC 地址是下一跳的路由器,路由器再转发下一个路由器,直到转发到和目标主机相连的路由器.
    • 发现目标 IP 地址是自己局域网内的主机,就会通过ARP(地址解析协议,ip–>MAC地址)请求获取目标主机的 MAC 地址,从而转发到这个服务器主机。
    • 转发的过程中,源 IP 地址和目标 IP 地址是不会变的(前提:没有使用 NAT 网络的),源 MAC 地址和目标 MAC 地址是会变化的。
  • 远端服务器处理请求,返回响应
  • 浏览器解析响应并渲染

电脑断网排查

先重启。
再看机器右下角网络连接的状态,初步判断是网络配置问题还是物理连接问题。
如果是物理连接的问题,验证所有网络硬件如网线、交换机、路由器是否正确连接。

  1. 使用命令行工具如 ipconfig或 ifconfig来看IP地址是否正确配置了
  2. 然后用 ping 命令测试本地网络和外部网络的连通性,以此来确定问题是在本地网络还是外部网络。
  3. 如果 ping IP地址成功但无法通过域名访问,这可能是DNS解析问题。可以尝试更换DNS服务器来测试是否解析问题。
  4. 检查防火墙,看是不是这些原因阻止了网络访问。
  5. 操作系统的网络系统日志看有没有什么错误信息。
  6. 运行网络诊断工具比如360、火绒等。
  7. 如果都不行,可能需要更专业的技术支持或是网络运营商来诊断网络问题。

TCP/IP五层网络模型

模型最大的优点就是把服务、接口还有协议这三个概念明确的区分开了,通过模型可以让不同系统的网络之间实现可靠的数据传输.
传输层数据带上TCP头,网络层带上IP头,数据链路层带上 MAC头等一系列操作。ping 是应用层命令
从主机 A 传输数据到主机 B 的过程可以简要描述如下:

  1. 应用层:是网络通信的最顶层,只专注于为用户提供应用功能,不用去关心数据是如何传输的。就类似于我们寄快递的时候,只需要把包裹交给快递员,由他负责运输快递,我们不需要关心快递是如何被运输的。
  • 比如 HTTP、FTP、DNS、SMTP等;应用层是工作在操作系统中的用户态,传输层及以下则工作在内核态。
  1. 传输层:
  • 传输层负责端到端的可靠数据传输。主机 A 中数据被传递给传输层,传输层将数据分割成合适的数据段,带上序号和校验信息等TCP头,形成传输层的数据报。TCP(传输控制协议)、UDP(用户数据报协议)。段 或 数据报
  1. 网络层:
  • 网络层负责网络互联和数据路由。主机 A 中传输层的数据报被传递给网络层,网络层根据目标主机 的 IP 地址,决定将数据报发送到主机 所在的网络。IP(互联网协议),ICMP(互联网控制消息协议)。包
  1. 数据链路层:
  • 下一层物理媒介上传输的数据会因为各种不可靠因素的影响而产生差错,为了弥补物理层上的不足,数据链路层主要对传输的数据进行检错和纠错。以太网(Ethernet),ARP(地址解析协议)。帧
  1. 物理层:
  • 透明的传送比特流,主要关注通过物理媒介来传输数据,比如网线、电缆、光纤等。比特(Bits)
    在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输
    当数据到达主机 B 后,整个过程会逆向进行,从物理层到应用层,直到数据被主机 B 的应用程序接收和处理

网络协议

Http & Https

HTTP 超文本传输协议, 是一个在计算机世界里两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
HTTP结构

  • 请求消息的内部第一行是请求行,请求行里包括了请求的方法、请求的路径、http版本号。
  • 第二行叫做请求头,这里面放着一些请求的附加信息,比如日期、语言、编码格式等等。
  • 第三行是空行。
  • 第四行开始就是请求体了,这里面就是需要发送的数据。对于GET方法来说,只用请求行和消息头web服务器就已经知道要做什么操作了,POST方法时表单填的信息就在消息体里。

HTTP状态码

http状态码可以分为五类:
1xx 类状态码是临时性响应,它属于提示信息,实际用到的比较少。
2xx 类状态码表示服务器成功处理了客户端的请求。
比如常见的[200 OK」表示一切正常。
3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,其实通常就是重定向。
比如「301」永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次来访问,浏览器会自动重定向到新的 URL。
「302」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
「304」表示资源没有被改过,客户端可以继续使用缓存资源。
4xx 类状态码表示客户端发送的报文有误,服务器无法处理,属于客户端的错误码了。
还要最常见的「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以服务器给不了我们。
5xx 类状态码表示客户端请求的报文没问题,但是服务器处理时内部发生了错误,属于服务器端的错误码。
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。

HTTP 常见字段

host字段,客户端发送请求时指定服务器的域名。
Content-Type 字段,用于服务器响应时告诉客户端,本次响应的数据是什么格式。
Content-Length 字段,服务器响应时,用 Content-Length 来表明本次响应的数据长度。

GET 和 POST

GET 和 POST 都是 HTTP 的请求方法。
get请求一般用来请求获取资源,这个资源可以是静态文本、页面、图片视频等等;post请求一般是根据请求对指定资源做出处理,比如提交数据、创建数据。
get请求的参数会显示在地址栏,安全性低,而且浏览器可能也会对参数长度进行限制;post请求则是将传递的参数放在请求体里面,不会在地址栏显示,安全性比get请求高,参数没有长度限制。
get请求刷新服务器或者回退没有影响;post请求回退时会重新提交数据请求。

HTTP1.1

HTTP 最突出的优点是 简单、灵活
1无状态,用 Cookie 解决
2明文传输,内容容易被窃取,用 HTTPS 解决

HTTP 与 HTTPS

  • HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 TLS 安全协议,使得报文能够加密传输。
  • HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 TLS 的握手过程,才可进入加密报文传输。
  • HTTP 默认端口号是 80,HTTPS 默认端口号 443。
    问题描述:HTTP的请求和响应都是明文传输,有安全隐患
    HTTPS:HTTPS并不是一个单独的协议,是在 TCP 和 HTTP 之间加入了 SSL/TLS 安全协议,使得报文能够加密传输,SSL是TLS的前身,现在使用的大多都是TLS。

对称加密与非对称加密

对称加密:发送方和接收方约定一个同样的规则也就是同一个密钥来对传输的信息进行加密和解密。
非对称加密:用两个密钥来进行加密和解密。公钥是所有人都可以得到的密钥,私钥是只有持有方才知道的密钥。一般情况下服务器拥有公钥和私钥,然后公布自己的公钥在网络上,客户端用这个公钥进行数据加密,此时只有服务器上的私钥才能进行解密。

TLS握手过程

TLS是同时使用了对称加密和非对称加密。

  • 首先服务器需要向CA证书授权中心申请证书来表明自己是经过验证的真实服务器,而不是伪造的。TCP三次握手后,然后开始TLS握手。
  • 客户端向服务器发送自己支持的TLS版本,支持的加密算法和一个随机数(第1个随机数)。
  • 服务器响应自己确认的TLS版本,加密的算法和自己生成的一个随机数(第2个随机数),并继续发送自己的证书和公钥。
  • 客户端验证服务器的证书后,会生成一个预主密钥(第3个随机数),并且用收到的公钥加密然后发送出去。
  • 服务器收到后用私钥解密得到客户端的预主密钥,此时只有客户端和服务器知道这个预主密钥是什么,除非私钥被泄漏了。
  • 然后客户端和服务器都使用预主密钥+第1随机数+第2随机数 计算出一个会话密钥。
  • 也就是到了这一步,前面的加密都是非对称加密,目的就是得到这个会话密钥,之后的实际数据传输都使用这个会话密钥进行加密解密,所以正常的数据传输部分用的就是对称加密了。
    HTTPS连接过程一定可靠吗
    有这么一种情况,客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间服务器」,客户端是和「中间服务器」完成了 TLS 握手,然后这个「中间服务器」再与真正的服务端完成 TLS 握手。
    从客户端的角度看,其实并不知道网络中存在中间服务器这个角色。那么中间服务器就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。
    但这有个前提,就是用户点击接受了中间服务器的证书。
    因为中间服务器与客户端的 TLS 握手过程中,会发送自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器识别出是非法的,于是就会提醒用户该证书存在问题。

HTTP和RPC

HTTP 和 RPC 都是基于 TCP 衍生出来的协议。
TCP 是70年代出来的协议
RPC 是80年代出来的
HTTP 是 90 年代才开始流行的
RPC又叫做远程过程调用,它本身并不是一个具体的协议,而是一种调用方式。它强调的是希望我们在调用远程方法的时候能够屏蔽细节,就想是在调一个本地方法的一样便捷。
现在很多C/S模式的软件作为客户端需要跟自己的服务端建立连接收发消息,这种情况下它们可以使用自家造的 RPC 协议,因为它只管连自己公司的服务器就 ok 了。
但对于浏览器来说,它不仅要能访问自家公司的服务器,还需要访问其他公司的网站服务器,因此它们需要有个统一的标准,不然大家没法交流。于是,HTTP 就是那个时代用于统一 B/S 的协议。
RPC,定制化程度更高,可以采用体积更小的 Protobuf 或其他序列化协议去保存结构体数据,也不需要像 HTTP 那样考虑各种浏览器行为,比如 302 重定向跳转啥的
HTTP 主要用于 B/S 架构,而 RPC 更多用于 C/S 架构。但现在其实已经没分那么清了,对外一般用 HTTP 协议,而内部集群的微服务之间则采用 RPC 协议进行通讯。

IP协议

IP 协议是网络层的核心协议之一,负责实现数据包的路由和转发,确保数据包能够从源地址传输到目的地址。
P 地址(IPv4 地址)由 32 位正整数来表示,每 8 位为组,共分为 4 组。
IP 地址是以网卡来配置的,有几个网卡就有几个ip地址
IPv4 的地址是 32 位的,IPv6 的地址是 128 位的,IPv6 可自动配置,即使没有 DHCP 服务器也可以实现自动分配IP地址,便捷到即插即用。
IP地址分类
IP 地址分类成了 5 种类型,分别是 A 类、B 类、C 类、D 类、E 类。A、B、C 类主要分为两个部分,网络号+主机号。D 类常被用于多播。E 类是预留的分类,暂时未使用。
第一位0:A类。第二位0:B类。。。
划分

  • 无分类地址 CIDR:不再有分类地址的概念, IP 地址被划分为两部分,前面是网络号,后面是主机号。10.100.122.2/24
  • 子网掩码:掩盖掉主机号,剩余的就是网络号。将子网掩码和 IP 地址按位计算 AND,就可得到网络号。
    子网掩码另一作用是子网划分,将主机地址分为两个部分:子网地址和子网主机地址。也就是网络地址+子网地址+主机地址。
    网络地址 192.168.1.0,使用子网掩码 255.255.255.192 对其进行子网划分。
    C 类地址中前 24 位是网络号,最后 8 位是主机号,根据子网掩码可知从 8 位主机号中借用 2 位作为子网号。
    由于子网网络地址被划分成 2 位,那么子网地址就有 4 个,分别是 00、01、10、11

DNS 域名解析协议

域名 --> IP 地址

ARP协议

IP 地址 --> MAC地址
在传输一个 IP 数据报的时候,确定了源 IP 地址和目标 IP 地址后,就会通过主机「路由表」确定 IP 数据包下一跳。而网络层的下一层是数据链路层,所以我们还要知道「下一跳」的 MAC 地址。
ICMP
ICMP 主要功能:确认 IP 包是否成功送达目标地址,报告发送过程中 IP 包被废弃的原因。

NAT

IPv4 的地址是非常紧缺的,在前面我们也提到可以通过无分类地址来减缓 IPv4 地址耗尽的速度,但是互联网的用户增速是非常惊人的,所以 IPv4 地址依然有被耗尽的危险。
提出网络地址转换 NAT ,缓解 IPv4 地址耗尽的问题。
简单的来说 NAT 就是同个公司、家庭、教室内的主机对外部通信时,把私有 IP 地址转换成公有 IP 地址。
比如有两个客户端 192.168.1.10 和 192.168.1.11 同时与服务器 183.232.231.172 进行通信,并且这两个客户端的本地端口都是 1025。
此时,两个私有 IP 地址都转换 IP 地址为公有地址 120.229.175.121,但是以不同的端口号作为区分。

DHCP协议

主要作用是态获取 IP 地址,DHCP 交互中全程都是使用 UDP 广播通信。

TCP

TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。

  • 面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息;
  • 可靠的:有一整套的保证数据可靠送达的安全机制;
  • 字节流:它在发送和接收数据时并不关心数据的边界,而是将数据视为连续的字节流进行传输。
    TCP格式头
  • 序列号:在建立连接时由计算机生成的随机数作为SYN初始值,每发送一次数据,就++。发送端和接收端利用这些序列号来重组数据包。确保数据包的正确顺序。
  • 确认应答号:下一次期望收到的数据的ACK序列号,发送端收到这个ack后可以认为在这个序号以前的数据都已被正常接收。用来解决丢包的问题。

TCP和UDP区别

1.连接
TCP 面向连接的,传输数据前先要建立连接。
UDP 是不需要连接,即刻传输数据。
2.交互个数
TCP 是一对一通信。
UDP 支持一对一、一对多、多对多的通信
3.可靠性
TCP 有重传机制、滑动窗口机制、流量控制、拥塞控制,数据可以可靠传输。
UDP 是尽最大努力交付,不保证可靠交付。
4.传输方式
TCP 是流式传输,面向字节流。
UDP 是一个包一个包的发送,面向报文。
5.适用场景
TCP适用于要可靠传输的场景,比如文件传输
UDP适用于对可靠性要求不高的实时应用,比如视频会议,直播等

实现一个可靠的UDP传输

在应用层实现:

  1. 数据报文编号:为每个发送的数据报文分配一个唯一的序列号,能够有序传输。
  2. 确认机制:接收方收到数据报后,发送一个确认消息回给发送方,确认消息包含接收到的数据报的序列号。
  3. 超时重传:发送方在发送数据报后启动一个定时器。如果在定时器超时之前没有收到确认,就重传数据报。
  4. 滑动窗口:使用滑动窗口机制来控制数据的发送速率和重传机制。窗口大小可以根据网络条件动态调整。
  5. 流量控制:根据接收方的处理能力调整发送速率,防止接收方被大量数据淹没。
  6. 拥塞控制:监测网络拥塞情况,并相应地调整数据发送速率,以减少丢包和网络拥塞。
  7. 数据完整性校验
  8. 错误恢复

Cookie和Session

cookie小饼干
它是浏览器保存在本地的一小块数据,一般不超过4KB。cookie 的出现是因为 HTTP 是无状态的机制,服务器记不住客户端的信息,可能我们每刷新一次网页,就要重新输入一次账号密码进行登录。
session会话
我们开一个浏览器,访问链接做一些操作,然后关闭浏览器,那这整个过程就称之为一个会话。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器会把客户端信息记录在服务器上。这样客户端的浏览器再次访问服务器时只需要从这个Session中查找这个浏览器的信息就可以了。
保存位置不同:cookie保存在浏览器端,session保存在服务端。
存储容量不同:cookie最多可以存放4kB,session则没有限制。
存储内容不同:cookie只能存储字符串,session存储结构类似于hashtable的结构,可以存放任何类型。
安全级别不同:Cookie 存储在客户端,它的内容容易被窃听或伪造,所以 Cookie 通常用来存储一些不敏感的数据;而 Session 信息存储在服务器端,安全级别会更高一些。

三次握手

  • 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态
  • 客户端初始化序号,将序号置于 TCP 首部的序列号字段中,同时把 SYN 标志位置为 1,表示 SYN 报文。 发送SYN 报文给服务端,向服务端发起连接,该报文不包含应用层数据,发送后客户端处于 SYN-SENT 状态。
  • 服务端收到客户端的 SYN 报文后,也随机初始化一个自己的序列号,填入 TCP 首部的序列号字段中。然后在 TCP 首部的确认应答号填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。
  • 客户端收到服务端报文后,初始化一个应答报文,TCP 首部 ACK 标志位置为 1 ,「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带实际数据,之后客户端处于 ESTABLISHED 状态。
  • 服务端收到客户端的应答报文后,也进入 ESTABLISHED 状态。
    为什么是三次握手?
    主要来说,三次握手主要是为了保证通信双方具有接收和发送的能力,并且三次握手也是防止历史连接初始化造成混乱的主要措施。
    如果是用两次握手,可能会出现历史连接问题:
    比如客户端发出连接请求,但因为网络延迟原因服务器没有收到,所以客户端第二次发送连接请求,这次服务器收到了然后返回确认开始连接传输释放连接。如果后面第一个经过延迟的请求到达了服务器,那服务端就会误以为客户端又发出了一个新的连接请求,于是就向客户端发出确认报文段,同意建立连接。而采用三次握手就可以解决这个连接的问题,减少不必要的资源浪费。

四次挥手

  • 客户端打算关闭连接,发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
  • 客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
  • 等待服务端处理完数据后,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
  • 客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
  • 服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态。
  • 客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态。
    如果服务端的第X次挥手丢失了,客户端就会触发超时重传机制,重传 xxx 报文,直到收到服务端的响应,或者达到最大的重传次数。如果还是没能收到服务端的 ACK 报文,那么客户端就会断开连接。
    为什么挥手需要四次?
    服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文表示我收到了你的FIN报文,但服务端现在可能还有数据需要处理和发送。
    等服务端数据处理完后,也会发送 FIN 报文给客户端来表示现在OK,我可以现在关闭连接了。
    从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,需要四次挥手。
    为什么 TIME_WAIT 等待的时间是 2MSL?
    首先MSL 是报文最大生存时间,超过这个时间报文将被丢弃。
    如果服务器没有收到断开连接的最后 ACK 报文,就会触发超时重发 FIN 报文,客户端接收到 FIN 后,会重发 ACK 给被动关闭方, 一来一去正好 2 个 MSL。
    服务器出现大量 TIME_WAIT 状态的原因
    首先如果服务器出现大量的 TIME_WAIT 状态的 TCP 连接,就是说明服务器主动断开了很多 TCP 连接。这可能是因为HTTP 没有在请求header里使用Keep-Alive长连接或者HTTP 长连接的请求数量达到上限。如果没有使用长连接,那么每次传数据的时候都要三次握手建立连接,传数据,然后四次挥手断开连接。

1、TCP重传机制

TCP 针对数据包丢失的情况,会用重传机制解决。
超时重传
就是在发送数据时,设定一个定时器,当超过指定的时间还没有收到对方的 ACK 确认应答报文,就会重发该数据。
RTT往返时延是数据包的往返时间,超时重传时间的值应该略大于报文往返 RTT 的值。
快速重传
不以时间为驱动,而是以数据驱动重传。
快速重传的工作方式是当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的报文段。
比如A给B发了1、2、3、4、5个报文,B收到1后应答2表示希望收到2,但是2丢失了,后面B收到3、4、5时都返回2,A收到了三个 Ack = 2 的确认,知道了 Seq2 还没有收到,就会在定时器过期之前,重传丢失的 Seq2。
【它依然面临着另外一个问题。发送方并不清楚这连续的 ACK2 是接收方收到哪个报文而回复的,是重传一个,还是重传所有的报文。】
选择性确认
在 TCP 头部「选项」字段里加一个 SACK数据,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。

2、滑动窗口

我们都知道 TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个。这种方式的效率比较低。
所以TCP引入了窗口这个概念,窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。窗口实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。而且还会有累计应答,只要发送方收到了 ACK xx 确认应答,就意味着 xx 之前的所有数据「接收方」都收到了,这样即使之前有应答丢失了也没事。

3、流量控制

发送方不能无脑的发数据给接收方,要考虑接收方处理能力。如果一直无脑的发数据给对方,但对方处理不过来,导致网络流量的无端的浪费。TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量。

  • TCP流量控制的主要机制是通过滑动窗口实现的。发送方根据接收方的窗口大小和网络情况动态调整自己的发送窗口大小。

4、拥塞控制

流量控制是避免「发送方」的数据填满「接收方」的缓存
拥塞控制是避免「发送方」的数据填满整个网络
拥塞窗口cwnd是发送方根据网络的拥塞程度而动态维护的一个的变量。
发送窗口的值 是拥塞窗口和接收窗口中的最小值。
拥塞控制三个阶段:慢启动-》拥塞避免-》拥塞发生

1、慢启动

有个ssthresh慢启动门限的变量
TCP 在刚建立连接完成后,首先是有个慢启动的过程,一点一点的提高发送数据包的数量,发包的个数是指数性的增长,也就是拥塞窗口1、2、4、8这样。
当 拥塞窗口cwnd 超过 ssthresh慢启动门限 时,开始「拥塞避免算法」。

2、拥塞避免

进入拥塞避免算法后,每当收到一个 ACK 时,拥塞窗口cwnd 增加 1,也就是变成了线性增长。所以还是增长阶段,只是增长速度缓慢了一些。

3、拥塞发生

一直增长后,网络就会慢慢进入拥塞的状况,于是就会出现丢包现象,需要对丢失的数据包进行重传。
我们知道,重传一般也就超时重传和快速重传。

  • 当发生了「超时重传」,则就会使用拥塞发生算法。
    ssthresh慢启动门限 设为 拥塞窗口的一半,拥塞窗口重置为 1(初始值),然后重新进入慢启动阶段。
    这种方式太激进,反应也很强烈,会造成网络卡顿。
  • 当发生了「快速重传」,使用快速恢复算法。
    快速恢复算法是认为,你还能收到 3 个重复 ACK 说明网络也不那么糟糕。此时慢启动门限和拥塞窗口都设为原拥塞窗口的一半,然后重新进入拥塞避免阶段;

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

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

相关文章

Oracle优化案例-教你在线搞定top cpu的sql(十二)

监控告警阈值load 大于10 SQL如下,太好用了 SELECT A.SQL_ID, A.SESS_COUNT, A.CPU_LOAD, B.SQL_TEXTFROM (SELECT SQL_ID,COUNT(*) SESS_COUNT,ROUND(COUNT(*) / SUM(COUNT(*)) OVER(), 2) CPU_LOADFROM V$ACTIVE_SESSION_HISTORYWHERE SAMPLE_TIME > SYSDATE…

[深度学习] 门控循环单元GRU

门控循环单元(Gated Recurrent Unit, GRU)是一种用于处理序列数据的递归神经网络(Recurrent Neural Network, RNN)变体,它通过引入门控机制来解决传统RNN在处理长序列时的梯度消失问题。GRU与长短期记忆网络&#xff0…

反射及动态代理

反射 定义: 反射允许对封装类的字段,方法和构造 函数的信息进行编程访问 图来自黑马程序员 获取class对象的三种方式: 1)Class.forName("全类名") 2)类名.class 3) 对象.getClass() 图来自黑马程序员 pac…

前端JS必用工具【js-tool-big-box】学习,数值型数组的正向排序和倒向排序

这一小节,我们说一下前端 js-tool-big-box 这个工具库,添加的数值型数组的正向排序和倒向排序。 以前呢,我们的数组需要排序的时候,都是在项目的utils目录里,写一段公共方法,弄个冒泡排序啦,弄…

JNI详解

JNI简介 Java是跨平台的语言,但在有的时候仍需要调用本地代码(这些代码通常由C/C编写的)。 Sun公司提供的JNI是Java平台的一个功能强大的接口,JNI接口提供了Java与操作系统本地代码互相调用的功能。 Java调C 1)使用…

Spring Boot 学习第八天:AOP代理机制对性能的影响

1 概述 在讨论动态代理机制时,一个不可避免的话题是性能。无论采用JDK动态代理还是CGLIB动态代理,本质上都是在原有目标对象上进行了封装和转换,这个过程需要消耗资源和性能。而JDK和CGLIB动态代理的内部实现过程本身也存在很大差异。下面将讨…

VMware vSphere 8.0 Update 3 发布下载 - 企业级工作负载平台

VMware vSphere 8.0 Update 3 发布下载 - 企业级工作负载平台 vSphere 8.0U3 | ESXi 8.0U3 & vCenter Server 8.0U3 请访问原文链接:https://sysin.org/blog/vmware-vsphere-8-u3/,查看最新版。原创作品,转载请保留出处。 作者主页&am…

Java面试八股之JVM内存溢出的原因及解决方案

JVM内存溢出的原因及解决方案 JVM内存溢出(Out Of Memory,OOM)通常是由于程序运行过程中内存使用不当造成的,常见原因及相应的解决方案如下: 原因及解决方案 内存中加载的数据量过大 原因:一次性从数据…

运维入门技术——监控的三个维度(非常详细)零基础收藏这一篇就够了_监控维度怎么区分

一个好的监控系统最后要做到的形态:实现Metrics、Tracing、Logging的融合。监控的三个维度也就是Metrics、Tracing、Logging。 Metrics Metrics也就是我们常说的指标。 首先它的典型特征就是可聚合(aggregatable).什么是可聚合的呢,简单讲可聚合就是一种基本单位可以在一种维…

Verilog刷题笔记48——FSM1型异步复位

题目: 解题: module top_module(input clk,input areset, // Asynchronous reset to state Binput in,output out);// parameter A0, B1; reg state, next_state;always (*) begin // This is a combinational always block// State transition logiccase(…

加拿大魁北克IT人士的就业分析

魁北克省作为加拿大东部的一个重要省份,近年来在IT行业的就业市场上展现出了强劲的增长势头。随着数字化转型的加速,魁北克对IT专业人士的需求日益增加,特别是在软件开发、网络安全、数据分析和人工智能等领域。 热门职位方面,软…

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》Chapter 9插图

禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》 Chapter 9插图

201.回溯算法:全排列(力扣)

class Solution { public:vector<int> res; // 用于存储当前排列组合vector<vector<int>> result; // 用于存储所有的排列组合void backtracing(vector<int>& nums, vector<bool>& used) {// 如果当前排列组合的长度等于 nums 的长度&am…

用 Rust 实现一个替代 WebSocket 的协议

很久之前我就对websocket颇有微词&#xff0c;它的确满足了很多情境下的需求&#xff0c;但是仍然有不少问题。对我来说&#xff0c;最大的一个问题是websocket的数据是明文传输的&#xff0c;这使得websocket的数据很容易遭到劫持和攻击。同时&#xff0c;WebSocket继承自HTTP…

【操作系统】操作系统发展简史

目录 1.前言 2.第一代&#xff08;1945~1955&#xff09;&#xff1a;真空管和穿孔卡片 3.第二代&#xff08;1955~1965&#xff09;&#xff1a;晶体管和批处理系统 4.第三代&#xff08;1965~1980&#xff09;&#xff1a;集成电路和多道程序设计 5.第四代&#xff08;1…

关于VMware遇到的一些问题

问题一&#xff1a;打不开磁盘…或它所依赖的某个快照磁盘&#xff0c;开启模块DiskEarly的操作失败&#xff0c;未能启动虚拟机 解决方法&#xff1a; 首先将centos 7关机&#xff0c;然后把快照1删掉 然后打开虚拟机所在目录&#xff0c;把提示的000001.vmdk全部删除&…

本地读取classNames txt文件

通过本地读取classNames,来减少程序修改代码,提高了程序的拓展性和自定义化。 步骤: 1、输入本地路径,分割字符串。 2、将className按顺序放入vector容器中。 3、将vector赋值给classNmaes;获取classNames.size(),赋值给CLASSES;这样,类别个数和类别都已经赋值完成。…

大厂面试官问我:Redis内存淘汰,LRU维护整个队列吗?【后端八股文四:Redis内存淘汰策略八股文合集】

往期内容&#xff1a; 大厂面试官问我&#xff1a;Redis处理点赞&#xff0c;如果瞬时涌入大量用户点赞&#xff08;千万级&#xff09;&#xff0c;应当如何进行处理&#xff1f;【后端八股文一&#xff1a;Redis点赞八股文合集】-CSDN博客 大厂面试官问我&#xff1a;布隆过滤…

vue3 Cesium 离线地图

1、vite-plugin-cesium 是一个专门为 Vite 构建工具定制的插件&#xff0c;用于在 Vite 项目中轻松使用 Cesium 库。它简化了在 Vite 项目中集成 Cesium 的过程。 npm i cesium vite-plugin-cesium vite -D 2、配置vite.config.js import cesium from vite-plugin-cesiumexp…

监测与管理:钢筋计在工程项目中的应用

在现代工程建设中&#xff0c;特别是大型长期工程项目&#xff0c;对结构安全性的监测与管理至关重要。钢筋计作为一种重要的监测工具&#xff0c;在工程项目中发挥着不可替代的作用。本文将探讨钢筋计在长期工程项目中的应用&#xff0c;包括安装方法、数据监测与分析以及实际…