【计算机网络】TCP协议超详细讲解

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,同步至SelectDB 1个月
简介: 【计算机网络】TCP协议超详细讲解

1. TCP简介

TCP协议广泛应用于可靠性要求较高的应用场景,如网页浏览、文件传输、电子邮件等。它提供了可靠的数据传输和流控制机制,能够确保数据的完整性和有序性。然而,由于TCP协议在传输过程中引入了较多的控制信息,因此相比于UDP协议,TCP的传输速度较慢。


2. TCP和UDP的区别

TCP

UDP

有连接

无连接

可靠传输

不可靠传输

面向字节流

面向数据报

全双工

全双工

是否连接: 可以想象成打电话,比如A给B打电话,只有建立好连接才能通信(交换数据),这种是有连接.而是用微信发消息,不需要建立连接则是无连接

是否可靠传输: 这里的可靠,并不是指A给B的数据一定完全能让B收到,只能确保B是不是收到了

字节流和数据报: TCP和文件IO一样基于 “流”,UDP则是以"数据报"为基本单位

全双工: 一个通道,双向通信

3. TCP的报文格式

398ee13bd0564592b7768d097b9ddf1d.png


源端口:表示发送方的端口号。


目标端口:表示接收方的端口号。


4位首部长度: 用于描述TCP报头有多长,这里的单位是4个字节.如果这里是1111->15,表示报头的长度是60


注: TCP的报头长度是可变的,在下面有一个选项(可有可无),可以有一个选项,也可以有多个.


TCP报头前面20个字节是固定的,后面的选项是可变的,选项可以是0个字节,最多是40个字节


保留位: 协议中预留的一些位,目前没有特定定义或使用规则。以便以后进行扩展或未来使用。


校验和:用于检测数据报的完整性


4. 确认应答机制

TCP是可靠的传输协议,确认应答机制是TCP保证可靠性的最核心机制!


在确认应答机制中,发送方在发送数据包后会等待接收方发送确认消息。如果发送方在一定的时间内没有收到确认消息,它会认为数据包丢失或发生错误,并会重新发送数据包。接收方通过发送确认消息来告知发送方数据包已成功接收,或者指示需要重发某个数据包。


1f02efb940fb4c9c82e12f7a36686e2c.png


普通报文: ACK这一位为0


应答报文: ACK这一位为1


特殊情况:如果客户端一次性给服务器发多条消息,那么浏览器的应答就会产生歧义


如下图:

ecfaa978d4354adc91b54b626b5e359d.png



在网络上有一种特殊情况,“后发先至”,后发的请求可能先到


7f69d1bc9b1e43bda945a8a2e1520b44.png


因此就会产生上述两种情况.


为了解决上述问题,就可以针对请求和应答报文进行编号!


232988b24d9b4a4eabd68525f9c4466b.png


跟对编号就可以很明确的分出是哪个请求的应答.即使出现"后发先至"的情况也没有问题


而这个编号就对应TCP报文结构中的32位序号和32位确认序号

119496772ae24c3495e4659bd17cc079.png



32位序号: 针对请求数据进行编号

32位确认序号: 针对应答(ACK)报文进行编号

注: TCP报头只能存一个序号,存的是最后一个字节的序号,是根据报文长度来算的


83ea2d12f59141429de73a3a6cffd8ed.png

上述数据的传输过程也不是一帆风顺的,可能会出现丢包,如果丢包,这就需要TCP的超时重传机制了


5. 超时重传

超时重传是当发送方发送数据包后,如果在一定的时间内未收到接收方的确认消息(ACK),发送方会认为数据包可能丢失或发生错误,并会重新发送该数据包。


超时重传机制的工作原理如下:


1.发送方发送数据包后,等待接收方的确认消息。

2.如果在设定的时间内,发送方未收到接收方的确认消息,就会认为数据包丢失或发生错误。

3.发送方会重新发送相同的数据包。

4.接收方收到重复的数据包时,会丢弃重复数据包,并发送之前已接收到的最后一个正确的确认消息。

5.发送方在收到接收方的确认消息后,继续发送下一个数据包。

超时时间如何确定?


一般操作系统中有一个配置项,描述超时时间的阈值.


如果第一次出现丢包,超出时间阈值后,进行重传.第二次的超时时间阈值就会比第一次更长.


如果重传几次依旧无法传输,就会重置TCP连接,如果还是连不上,就会直接释放连接


超时重传会出现两种情况:


1.数据报丢了

2.ack丢了

对于这两种情况发送方都区分不了这两种情况,对于第二种情况,接收方就会收到重复的数据,但可以根据序号进行去重


6. 三次握手

三次握手是在TCP协议中建立一个可靠的连接所使用的一种机制。它由发送方和接收方之间进行的三次通信组成,用于确保双方都愿意建立连接,并同步各自的初始序列号。


三次握手类似于打电话


如下图:


7be0405f93cf4552b6eabccf44f8ca4b.png


三次握手的过程本质上是四次数据的交互.只是中间两条数据可以合并到一起


如下图所示:

121ec0e0f6d94add98f3c703a1de1a3b.png



三次握手的步骤:


1.第一次握手(SYN):发送方向接收方发送一个带有SYN标志的数据包(SYN包),请求建立连接。发送方会随机选择一个初始序列号,并将它放在SYN包中的序列号字段中发送给接收方。

2.第二次握手(SYN+ACK):接收方收到SYN包后,会向发送方发送一个带有SYN和ACK标志的数据包(SYN+ACK包),表示接受建立连接的请求,并回复确认号(ACK)和自己的初始序列号。接收方还会随机选择一个初始序列号,并将它放在SYN+ACK包中的序列号字段中发送给发送方。

3.第三次握手(ACK):发送方收到SYN+ACK包后,会向接收方发送一个带有ACK标志的数据包(ACK包),确认接收方的确认号,并发送自己的确认号。接收方收到ACK包后,会确认发送方的确认号,并完成连接的建立。

为什么要建立连接以及建立连接的意义:


1.检查一下当前的网络情况是否畅通

2.三次握手也是在检查通信双方的发送能力和接收能力是正常的

3.三次握手过程中,也在协商一些重要的参数

两个重要的TCP状态:


1.LISTEN:表示服务器正在监听来自客户端的连接请求。服务器在LISTEN状态下,等待客户端发起连接请求。

2.ESTABLISHED:表示TCP连接已经建立,双方可以进行数据的传输。在ESTABLISHED状态下,双方可以互相发送数据包。


7. 为什么两次握手不行?

1、阻⽌重复历史连接的初始化(主要原因)


当旧的SYN报文先到达服务端,服务端回一个ACK+SYN报文

客户端收到后可以根据自身的上下文,判断这是一个历史连接(序列号过期或超时) ,那么客户端就会发送 RST 报文给服务端,表示中止这一次连接。

两次握手在收到服务端的响应后开始发生数据,不能判断当前连接是否是历史连接。


2、同步双方的初始序列号

TCP 协议的通信双方,都必须维护一个[序列号], 序列号是可靠传输的一个关键因素


接收端可以去除重复数据

接收端可以按照序列号顺序接收

标识发送的数据包,哪些已经被收到

两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。


3、避免资源浪费


两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求 SYN 报文,而造成重复分配资源。

只有两次握手时,如果客户端的SYN请求连接在网络中阻塞,客户端没有收到服务端的ACK报文,会重新发送SYN。

由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接。

8. 四次挥手

四次挥手是在TCP协议中用于终止一个已建立的连接的机制。它是TCP连接的正常关闭流程,由发送方和接收方之间进行的四次通信组成。


以下是四次挥手的步骤:


1.第一次挥手(FIN):发送方向接收方发送一个带有FIN标志的数据包(FIN包),表示发送方已经完成数据的发送,希望关闭连接。发送方不再发送数据,但仍然可以接收数据。

2.第二次挥手(ACK):接收方收到FIN包后,向发送方发送一个带有确认号(ACK)的数据包,表示已接收到发送方的关闭请求。接收方仍然可以发送数据。

3.第三次挥手(FIN):接收方向发送方发送一个带有FIN标志的数据包(FIN包),表示接收方也希望关闭连接。接收方停止发送数据,但仍然可以接收数据。

4.第四次挥手(ACK):发送方收到FIN包后,向接收方发送一个带有确认号(ACK)的数据包,表示已接收到接收方的关闭请求。发送方不再发送数据,也不再接收数据。

85707d99a2944f859a1af6cd58fb0d2c.png


两个重要的TCP状态:


1.CLOSE_WAIT:表示TCP连接的一方已经收到了对方的连接终止请求(FIN包),并发送了确认(ACK包)。在CLOSE_WAIT状态下,接收方等待应用层处理完数据后的连接关闭。

2.TIME_WAIT:表示TCP连接的一方已经发送了连接终止请求(FIN包),并收到了对方的确认(ACK包)。在TIME_WAIT状态下,发送方等待一段时间后,保持连接状态清理(ACK包没有丢包),并释放资源。


9. 滑动窗口

TCP能保证可靠传输,但失去了效率.为了在保证可靠性的前提下,尽可能的提高效率,就有了滑动窗口机制


滑动窗口是在数据传输中用于流量控制和可靠传输的一种机制。它允许发送方在不等待接收方确认的情况下连续发送多个数据包,提高了传输效率。


在不引入滑动窗口的情况下:

23385f4f8ff740fbb333cab65be0e638.png



发送方和接收方一应一答,可靠性确实能得到保证,但其实大部分的时间都消耗在等待ACK上了.


因此滑动窗口就是每次批量发送一波消息,然后在等一波ACK,再发一波消息


如下图所示:



bbab426f69764e5087f563068740977b.png

99f35dff975c42cfbbfffbca6ccb8594.png




上图中窗口大小是3000,主机A发送了3000字节的数据,主机B需要确认应答,如果第一个ack成功返回主机A,说明1~1000的数据发送成功,窗口就会向后移动,并发送下一条数据,保证窗口中的数据都是需要确认应答的,或者是没发出去的.


上述过程都是正常的情况下,但也会发送丢包或者乱序的情况


情况1:数据包到了,但是ACK丢了


168c49a1d1a84f528aba2a6a0d9f090c.png


如上图第二个ack丢了,不用做任何处理也没关系,对于可靠传输没有任何影响.右边ack的数字,1001表示1001之前的数据都受到了,2001表示2001之前的数据都受到了,3001表示3001之前的数据都受到了.(后者包括前者).


情况2:数据包丢了

63e9e8d2fd3c48669436f04559c25d9d.png



假设11000的数据包丢了,.在11000的数据开始丢的时候,主机A并不知道丢了数据,会继续往下发数据.


那么主机B会在收到01000的数据前的应答中返回1001,主机A在接收到重复的几次确认之后,会重新发送11000的数据.当主机B收到11000的数据后,会把应答的数据变成最新的,例如在主机A重发01000的数据前又发了30006000的数据,并且没有丢包,在收到01000的数据后,下此应答的数字就是6001.


上述的重传过程,效率也是比较高的,并没有耽误后续数据的发送,这个称为"快速重传".


10. 流量控制

对于滑动窗口的大小,也并不是随意设置的.如果超出接收方的处理速度,就可能会丢失一些数据,那就还得重传这些数据.效率还得不到提升. 因为又有了流量控制机制


流量控制是在数据通信中的一种机制,用于控制发送方的数据发送速率,以适应接收方的处理能力,避免数据的丢失或拥塞。


接收方使用接收缓冲区的剩余空间大小,来作为发送方速率(滑动窗口大小)的参考数值


例如一个水桶,发送方就是往桶里放水,接收方就是出水.进水和出水的速度,就决定了 水位的高低


接收方会在收到发送方的数据后,会在返回的ACK报文中,把当前缓冲区的剩余空间大小,反馈给发送发


对应着TCP报文结构中的16位窗口大小.

1f1de68b451a4fb6bc04fbf572df0a4f.png



在TCP报文结构的选项中,有一个用于调整窗口大小的扩展因子.用于跳转滑动窗口的大小,并不是说窗口的大小最大只能是16位(64KB)


11. 拥塞控制

拥塞控制是用于控制在网络中发生拥塞时的数据传输速率。当网络中的流量过大,导致网络拥塞时,TCP拥塞控制机制会自动减少发送方的数据传输速率,以避免进一步加剧网络拥塞。


流量控制只是考虑了接收方的处理速率,但数据的传输还要经过很多的交换机和路由器.因此我们也要考虑这些中间结点的速率.


拥塞控制机制主要包括四个算法:慢启动、拥塞避免、快重传和快恢复。


慢启动算法是在TCP连接建立时,发送方初始的数据传输速率较低,然后逐渐增加发送方的数据传输速率,直到网络出现拥塞为止。


拥塞避免算法是在慢启动阶段结束后,发送方以线性增加的方式增加数据传输速率,以避免过快地增加网络流量。


快重传算法是当接收方收到重复的数据包时,会立即发送一个重复确认,以通知发送方有数据包丢失,从而使发送方能够更快地重传丢失的数据包。


快恢复算法是在接收到重复确认后,发送方将拥塞窗口减半,然后继续进行拥塞避免算法,以减少网络拥塞的影响。


对于流量控制和拥塞控制,本质上都是在控制窗口的大小,在实际中较小的那个作为窗口的大小


12. 延时应答

延时应答是指在TCP通信中,当一方发送数据给另一方时,接收方需要向发送方发送一个确认应答,表示已经成功接收到数据。延时应答是指接收方在接收到数据后,不立即发送确认应答,而是等待一段时间后再发送确认应答。


如下图:


1cb93cbf106e427dbf7fcee20da5c7c3.png


接收方在收到发送方的数据后,不会立即返回应答,而是接收方先进行一部分数据的处理然后再返回应答给发送方.


延时应答的主要作用是为了优化网络传输性能。TCP协议使用了滑动窗口机制,发送方会根据接收方发送的确认应答来确定下一次发送的数据量。如果接收方立即发送确认应答,那么发送方会立即发送下一批数据,造成网络拥塞。而延时应答可以让发送方在一定时间内累积多个数据包,然后一次性发送确认应答,有效减少了网络流量。


13. 捎带应答

捎带应答是指在TCP通信中,接收方发送确认应答时,可以同时携带自己发送的数据。也就是说,在发送确认应答的同时,可以将自己需要发送的数据一起发送出去。


在网络通信中,典型的通信模型是一发一收


在TCP中,只要把数据发送过去,就会立即由内核返回一个ack报文.响应数据则是由应用程序里进行负责传输.


由于上述两个操作是不同时机传输的,原本是不能把这两个操作合并的,但是因为"延时应答"的存在,会等一会,因此就把上述两操作合并了


捎带应答的主要目的是为了减少网络传输的延迟和减少网络负载。在TCP通信中,接收方发送确认应答时会占用网络资源,而且会增加延迟。通过捎带应答,接收方可以在发送确认应答的同时,将自己需要发送的数据一起发送给发送方,减少了网络传输的次数和延迟。


14. 面向字节流

面向字节流是指TCP协议在传输数据时将数据视为连续的字节流进行处理,而不是将数据分割成固定大小的块进行传输。


在TCP通信中,发送方将待发送的数据按照字节流的方式发送给接收方,接收方按照相同的字节流方式接收数据,并将数据重新组装成原始的数据块。


在面向字节流中,有一个问题,叫做"粘包问题"


粘包问题是指在TCP通信中,发送方将多个小的数据包连续发送给接收方时,接收方可能会将这些数据包合并成一个大的数据包,导致数据的粘连,造成数据解析错误。


就比如我们看一篇没有标点符号的文章,对于那些字是一句话是有很多看法的.TCP也是如此,无法确定哪些是一个完整的应用层数据报


要想解决"粘包问题",有两种办法:


1.通过分隔符,约定某个符号作为包的结束标记

2.通过指定包的长度,比如在数据包的开头位置声明长度

上述方法在自定义的应用层协议,就有典型的实现:


xml: 分隔符就是结束标签

json: 分隔符就是}

protobuf: 通过声明长度来确定边界

http: 分隔符+长度

15. TCP的连接异常处理

TCP协议在连接异常处理方面主要涉及以下几个方法:


1.程序崩溃

2.正常关机

3.主机突然关机

4.网线断开

程序崩溃就是进程异常退出,操作系统会回收进程的资源,包括释放文件的描述符表,相当于调用了socket里的close方法,进而触发FIN报文进行四次挥手


正常关机,系统会强制结束所有进程,那么就和程序崩溃的情况是一样的,进行四次挥手


主机突然关机:


如果是接收方突然关机,发送方并不知道,就会继续发送数据,但发送方收不到ack报文,就会触发超时重传,如果重传几次后,依旧没有应答,就会重置连接,最后放弃连接

如果是发送方突然关机,接收方就只能等着,等一阵之后,就会发送一个"心跳包",确认连接是否正常

心跳包通常是一个小的数据包,由发送方定期发送给接收方。接收方在收到心跳包后,会立即发送一个确认应答给发送方,表示连接仍然活跃。如果发送方在一定时间内没有收到接收方的确认应答,就可以认为连接已经失效,可以进行相应的处理,如关闭连接或重新建立连接。


网线断开与主机突然关机的处理方式相同,分两种情况处理.


ceee97b453764aae898826f60e904ef5.gif

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
2月前
|
数据采集 算法 数据挖掘
模块化控制协议(MCP)在网络中增强智能体执行效率的研究
随着Web3技术的迅速发展,去中心化应用和智能体在各种领域的应用逐渐增多。MCP(Modularized Control Protocol,模块化控制协议)作为一种增强智能体执行能力的关键技术,为Web3场景中的智能体提供了更强的灵活性和可扩展性。本文将探讨如何利用MCP技术提升智能体在Web3场景中的执行能力,并通过实例代码展示其实现路径。
153 22
|
4月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
119 18
|
5月前
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
141 22
|
5月前
|
网络协议 数据安全/隐私保护 网络架构
|
6月前
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
199 12
|
6月前
|
缓存 网络协议 API
掌握网络通信协议和技术:开发者指南
本文探讨了常见的网络通信协议和技术,如HTTP、SSE、GraphQL、TCP、WebSocket和Socket.IO,分析了它们的功能、优劣势及适用场景。开发者需根据应用需求选择合适的协议,以构建高效、可扩展的应用程序。同时,测试与调试工具(如Apipost)能助力开发者在不同网络环境下优化性能,提升用户体验。掌握这些协议是现代软件开发者的必备技能,对项目成功至关重要。
|
7月前
|
人工智能 自然语言处理 决策智能
智能体竟能自行组建通信网络,还能自创协议提升通信效率
《一种适用于大型语言模型网络的可扩展通信协议》提出创新协议Agora,解决多智能体系统中的“通信三难困境”,即异构性、通用性和成本问题。Agora通过标准协议、结构化数据和自然语言三种通信格式,实现高效协作,支持复杂任务自动化。演示场景显示其在预订服务和天气预报等应用中的优越性能。论文地址:https://arxiv.org/pdf/2410.11905。
181 6
|
9月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
210 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
7月前
|
网络协议 测试技术 Linux
Golang 实现轻量、快速的基于 Reactor 模式的非阻塞 TCP 网络库
gev 是一个基于 epoll 和 kqueue 实现的高性能事件循环库,适用于 Linux 和 macOS(Windows 暂不支持)。它支持多核多线程、动态扩容的 Ring Buffer 读写缓冲区、异步读写和 SO_REUSEPORT 端口重用。gev 使用少量 goroutine,监听连接并处理读写事件。性能测试显示其在不同配置下表现优异。安装命令:`go get -u github.com/Allenxuxu/gev`。
111 0
|
9月前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法

热门文章

最新文章