IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 网络详解之TCP -> 正文阅读

[网络协议]网络详解之TCP

1 TCP基本认识

1.1 什么是TCP

TCP 是面向连接的可靠的基于字节流的传输层通信协议。
在这里插入图片描述

面向连接:一定是「一对一」才能连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息,也就是一对多是无法做到的;
可靠:TCP可以保证在网络波动下数据包也能到达接收端
字节流:应用程序对数据的发送和接收是没有边界限制的。所以在封装TCP数据包的时候需要标注出消息的边界从而确保用户能够正确读到信息.

1.2 什么是TCP连接

用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。

其中:
Socket:由 IP 地址和端口号组成
序列号:用来解决乱序问题等
窗口大小:用来做流量控制

💡小知识

通过TCP四元组(源地址,源端口,目的地址,目的端口)可以唯一确定一个连接

1.3 TCP报头格式

在这里插入图片描述

序列号:在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机,每发送一次数据,就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。
确认应答号:指下一次「期望」收到的数据的序列号,发送端收到这个确认应答以后可以认为在这个序号以前的数据都已经被正常接收。用来解决丢包的问题。

控制位:

控制位:
ACK:该位为 1 时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的 SYN 包之外该位必须设置为 1 。
RST:该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接。
SYN:该位为 1 时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定。
FIN:该位为 1 时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位为 1 的 TCP 段。
URG:紧急指针是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

2 TCP保证传输可靠的机制

2.1 确认应答

在这里插入图片描述

确认应答就是发送方发送数据的时候接收方会返回一个确认应答(ACK)从而保证发送方数据已经被接收.

TCP将每个字节的数据都进行了编号。即为序列号。每一个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

在这里插入图片描述

2.2 超时重传

超时重传就是在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据.

情况一:数据包丢失
在这里插入图片描述

主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发;

情况二:确认应答丢失
在这里插入图片描述

在这种情况下,由于发送方在规定的时间内未收到ACK,所以重发了数据,但是这样会导致接收端收到很多重复的数据,这个时候TCP内部就会有一个去重操作,当接收到数据时,TCP会检查该数据对应的序列号是否已经存在于接收缓冲区内,如果存在就舍弃该数据包,否则就接收.

超时重传时间是以 RTO (Retransmission Timeout 超时重传时间)表示,一般它的设定值会略大于RTT (包的往返时间)。如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍。也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接。

2.3 连接管理

2.3.1 TCP连接建立

TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。三次握手的过程如下图:
在这里插入图片描述

第0步:服务端端口处于Listen状态等待连接

第1步:客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN-SENT 状态

第2步:服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN-RCVD 状态。

第3步:客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据之后客户端处于 ESTABLISHED 状态。,服务端接收到客户端的应答报文后也处于ESTABLISHED 状态

当连接双方都处于ESTABLISHED状态时连接成功建立,此时双方可以互发数据了.

💡:为什么要进行三次握手?
1:首先进行三次握手最重要的原因是为了避免旧的重复连接初始化造成混乱
在这里插入图片描述

在当前情况下客户端多次发送SYN报文,并且由于网络拥堵的情况下旧报文先一步到达了服务端,此时服务端会响应相应的SYN + ACK报文,当报文到达客户端时,客户端发现当前ACK报文不是自己期望的,所以就会返回RST报文中断本次连接,当新报文到达后再次进行三次握手从而建立连接.

在上述情况下如果是两次挥手那么服务端收到SYN报文时就会建立连接并且发送数据,当数据报文到达客户端后客户端发送RST报文中断连接直到新的SYN报文到达才真正建立连接.这种情况下会导致服务端建立起历史连接并且发送了无效数据,从而导致服务器端资源浪费,要解决这种现象,最好就是在「被动发起方」发送数据前,也就是建立连接之前,要阻止掉历史连接,这样就不会造成资源浪费,而要实现这个功能,就需要三次握手。

2:同步双方序列号

序列号是可靠传输的关键,它可以让接收方借此去重,并且可以根据序列号按序接收从而保证数据的顺序不会乱,同时它可以让发送方知道哪些数据已经被接收方接收

当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,同时当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。

💡:四次握手也能实现同步双方序列号,但是由于第二步和第三步可以合并,所以采用三次握手从而提高效率,两次握手只能保证一方的序列号被接收和确认,没法保证双方的序列号都能被确认.

3:避免造成资源浪费
在这里插入图片描述

在两次握手的情境下,如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。

🔥:当第三次连接丢失会发生什么?

因为这个第三次握手的 ACK 是对第二次握手的 SYN 的确认报文,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。
注意,ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。

2.3.2 TCP连接断开

在这里插入图片描述

  • 客户端需要关闭本次连接的时候就会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
  • 服务端接收到FIN报文后响应一个ACK报文,同时自身进入CLOSED_WAIT状态
  • 服务器处理完数据后也会发送一个FIN报文,同时自身进入LAST_ACK状态
  • 客户端收到FIN报文后响应ACK报文,自身进入TIME_WAIT状态
  • 服务端收到ACK报文后就进入了 CLOSED 状态,至此服务端已经完成连接的关闭。
  • 客户端经过2MSL的时间后也会自动进入CLOSED状态,至此客户端已经完成连接的关闭。

注意:哪一方主动关闭哪一方有TIME_WAIT状态

要进行四次挥手的原因:

关闭连接时,客户端向服务端发送FIN包只是说明客户端不再发送数据了,但是客户端还是能接受数据,服务器收到FIN包后返回ACK包后还需要进行最后的数据处理和发送,当处理完毕后发送FIN报文从而进行后续的关闭操作,综上所知服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK 和 FIN 一般都会分开发送,从而比三次握手多了一次。

🔥:为什么 TIME_WAIT 等待的时间是 2MSL?

MSL 是 Maximum Segment Lifetime,报文最大生存时间,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。如果接收方没有收到最后一个ACK报文,那么就会重发FIN报文,这样一去一来正好最多不超过2MSL,所以这里是能够允许最后一次ACK报文丢失一次从而确保两方都能正常关闭连接.至于为啥不是更大的等待时间是由于连续两次丢包的概率太低,在这个角度忽略该问题比解决更具有性价比.

💡:小知识

MSL 应该要大于等于 TTL (IP 数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减 1,当此值为 0 则数据报将被丢弃,同时发送 ICMP 报文通知源主机)消耗为 0 的时间,以确保报文已被自然消亡。

🔥:为什么需要 TIME_WAIT 状态?

1:防止历史连接中的数据,被后面相同四元组的连接错误的接收;
如果TIME_WAIT 时间过短或者没有,那么上一次连接的报文可能被下一次连接所接受从而导致数据混乱,当TIME_WAIT 时间为2MSL时能够保证上次连接的数据都自然消失在网络中从而保证本次连接的数据都是最新的数据包.
2:保证「被动关闭连接」的一方,能被正确的关闭;
如果TIME_WAIT 时间过短或者没有,那么当最后一次ACK报文丢失后,服务器重传FIN报文时客户端已经关闭连接了,所以会返回RST报文导致服务器端的异常终止.所以需要TIME_WAIT 状态来确保服务器能够正常关闭.

2.4 滑动窗口

我们都知道 TCP 是每发送一个数据,都要进行一次确认应答。当上一个数据包收到了应答了, 再发送下一个.但是这样效率是比较低的,为解决这个问题,TCP 引入了窗口这个概念。窗口大小就是指无需等待确认应答,而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间,发送方主机在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答,此时数据就可以从缓存区清除。

在这里插入图片描述
那么如果出现了丢包,如何进行重传?
情况1:数据包已被接收,但是ACK丢了
在这里插入图片描述

这种情况只需等后续ACK报文即可,比如通过ACK为40=001就可以知道前4000个字节的数据已经被接收了,此时ACK为3001的报文丢失就没啥影响了.

情况2:数据包丢了
在这里插入图片描述

当客户端传输的数据丢失后,服务器端会连续回复几个相同的ACK报文来获取缺失的数据,当客户端连续收到3个重复的ACK时会触发快速重传从而将缺失的数据发送给服务器,当服务器收到缺失的数据后会响应最新的ACK报文从而让客户端继续发接下来的一组数据.

💡:小知识

接收窗口和发送窗口的大小并不是完全相等,因为随着应用读取接收缓存区数据接收窗口是一直在变化的,而窗口大小是通过TCP包发送的,这中间会有一定延时从而导致二者不相同.

2.5 流量控制

在滑动窗口的前提下,发送窗口需要根据接收缓冲区剩余空间的大小来灵活调整从而保证双方读取数据的速度匹配,从而避免发送速度过快导致接收方丢弃数据.

接收方会通过ACK报文中的窗口大小来告知发送方当前接收方剩余空间大小,发送方收到该报文后就会调整发送窗口大小.如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

在这里插入图片描述

其中选项中还包含一个窗口扩大因子M,实际窗口大小是串口大小字段值左移M位.

2.6 拥塞控制

前面的流量控制是避免「发送方」的数据填满「接收方」的缓存,但是并不知道网络的中发生了什么。一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。所以为了避免发送方数据由于网络拥堵充斥着整个网络引入了拥塞控制机制.

慢启动机制:
在这里插入图片描述

最开始初始窗口为1个单位(具体是一个字节还是10个字节取决于操作系统的实现),并且以指数程度增长,当窗口大小达到慢启动门限时窗口时就会进入线性增长,当出现丢包时(即网络拥堵)将慢启动门限减半,然后窗口大小又开始从1个单位开始.

发送窗口的最终大小为拥塞窗口和流量控制窗口的最小值

2.7 延时应答

延时应答就是接收方接收到数据后稍微晚点回复ACK报文,从而尽量让回复的窗口大小能大一点.

2.8 捎带应答

捎带应答是延时应答的延伸,当ACK报文延时一段时间后可能会导致ACK的返回时机和发送数据的时机重合,这个时候就可以把这两者合并发送.

在这里插入图片描述

2.9 面向字节流(粘包问题)

TCP粘包问题就是指在TCP接收缓冲区中若干个应用包混在一起了从而区分不出来哪到哪是一个数据包.

解决办法:

在应用层协议中加入包之间的边界,比如aaa;bbb;ccc这里的分号就可以作为数据包之间的边界方便应用正确的获取数据.

2.10 TCP的异常处理

1:进程终止

如果直接终止进程,那么进程对应的PCB就没了,即里面的文件描述表没了,此时文件就相当于自动关闭了,同样会进行四次挥手

2:机器关机

正常流程的关机操作系统会先杀死所有进程再关机,这就和上述情况一样了.

3:机器断电或者网断开

在这种情况下操作系统不会有任何的处理措施.

3 TCP和UDP的比较

UDP提供无连接的服务

在这里插入图片描述

目标和源端口:主要是告诉 UDP 协议应该把报文发给哪个进程。
包长度:该字段保存了 UDP 首部的长度跟数据的长度之和。
校验和:校验和是为了提供可靠的 UDP 首部和数据而设计,防止收到在网络传输中受损的 UDP包。

区别1:连接

TCP 是面向连接的传输层协议,传输数据前先要建立连接。
UDP 是不需要连接,即刻传输数据。

区别2:服务对象

TCP 是一对一的两点服务,即一条连接只有两个端点。
UDP 支持一对一、一对多、多对多的交互通信

区别3:可靠性

TCP 是可靠交付数据的,数据可以无差错、不丢失、不重复、按需到达。
UDP 是尽最大努力交付,不保证可靠交付数据。

区别4:拥塞控制、流量控制

TCP 有拥塞控制和流量控制机制,保证数据传输的安全性。
UDP 则没有,即使网络非常拥堵了,也不会影响 UDP 的发送速率。

区别5:首部开销

TCP 首部长度较长,会有一定的开销,首部在没有使用「选项」字段时是 20 个字节,如果使用了「选项」字段则会变长的。
UDP 首部只有 8 个字节,并且是固定不变的,开销较小。

区别6:传输方式

TCP 是字节流式传输,没有边界,但保证顺序和可靠。
UDP 是一个包一个包的发送,是有边界的,但可能会丢包和乱序。

区别7:分片不同

TCP 的数据大小如果大于 MSS(TCP数据包每次传输的最大数据分段大小) ,则会在传输层进行分片,目标主机收到后,也同样在传输层组装 TCP 数据包,如果中途丢失了一个分片,只需要传输丢失的这个分片。
UDP 的数据大小如果大于 MTU (最大传输单元,即物理接口(数据链路层)提供给其上层(通常是IP层)最大一次传输数据的大小),则会在 IP 层进行分片,目标主机收到后,在 IP 层组装完数据,接着再传给传输层。

在这里插入图片描述
TCP 和 UDP 应用场景:
由于 TCP 是面向连接,能保证数据的可靠性交付,因此经常用于:

FTP 文件传输;
HTTP / HTTPS;

由于 UDP 面向无连接,它可以随时发送数据,再加上UDP本身的处理既简单又高效,因此经常用于:

包总量较少的通信,如 DNS 、SNMP 等;
视频、音频等多媒体通信;
广播通信;

💡 :小知识

UDP 头部没有「首部长度」字段,而 TCP 头部有「首部长度」字段,这是因为TCP的首部长度是在变化的,而UDP的首部长度固定为8个字节,所以无需多一份空间来单独保存UDP首部长度.

作者水平有限,若文章有任何问题欢迎私聊或留言,希望和大家一起学习进步!!!
本文中部分图片取自小林图解网络,创作不易,再次希望大家👍支持下,谢谢大家🙏

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:57:20  更:2022-07-17 16:58:51 
 
开发: 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年12日历 -2024/12/28 20:20:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计