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

简介: TCP是面向字节流的,可以多次的接收和发送,对于应用层来说,一连串的字节数据,不知道从哪到哪算一个完整的应用层数据包,对应发送多少次算一个应用层完整格式的数据,和接收多少次算一个应用层完整格式的数据就不知道了

1. TCP协议头部格式

image.png


源/目的端口:表示数据从哪个进程发送,发送到哪个进程去

32位序号:发送的数据按照一个字节一个编号存放进去

32位确认号:用于给对方的响应,值为收到TCP报文段的序号值加1

4位TCP报头长度:表示TCP头部有4个字节(32位),所以TCP头部最大长度为15*4=60

6个boolean值标志位:

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

RST:对方要求重新建立连接,把携带RST标识的称为复位报文段

SYN:请求建立连接,把携带SYN标识的称为同步报文段

FIN:通知对方,要关闭连接了,把携带FIN标识的称为结束报文


16位窗口大小:进行流量窗口控制

16位校验和:检验数据是否一致

16位紧急指针:标识哪部分数据是紧急数据

2. TCP协议原理

TCP协议是对数据传输提供的一个管控机制,主要体现在可靠和效率两个方面,即在保证数据可靠传输的情况下尽可能的提高效率


2.1 可靠传输机制

2.1.1 确认应答机制

向对方发送一个数据报,对方要返回一个确认应答的数据报


实现的方式:

image.png



说明:


发送的数据是基于TCP报头中的“32位序号”来保存的,一个字节对应一个序号

确认应答的数据是基于TCP报头中的“32位确认序号”来保存的,ack(确认信息)标志位置为1,返回某个序列号,说明某个序列号之前的数据全部接收到

有了确认应答,它才可以继续发送后边的数据

2.1.2 超时重传机制

发送的数据报可能因为网络拥堵等原因,超过一定时间,还没有收到确认应答的数据报,就需要重新发送


没有收到确认应答,可能是因为发送数据时候就已经发生了丢包

 image.png


也可能是因为ACK丢包了

微信图片_20221030151657.png

这种情况,主机B可能会接收到许多重复的数据,基于TCP协议报头中的“32位序号”可以识别到哪些包是重复的包,并把重复的包丢掉,达到去重的效果


超时时间如何确定?


如果超时时间设置的太长,会导致重传的效率

如果超时时间设置的太短,会导致频繁发送重复的数据


因此TCP协议为了保证在任何环境中都能有较高性能的通信,系统会动态的计算这个超时时间


超时以500ms为一个单位,每次判定超时重发的时间都是500ms的整数倍

重发一次,仍然不能收到应答,等待2*500ms后再进行重传

仍然等不到应答,等待4*500ms进行重传,以此类推,以指数形式增长

累积到一定重传次数,TCP协议认为网络或者对端主机出现异常,强制关闭连接

2.1.3 连接管理机制(三次握手,四次挥手)

真正发送数据之前,要先通过三次握手建立连接,不需要发送数据了,通过四次挥手断开连接


三次握手

image.png

 


客户端向服务端发送SYN,申请建立客户端到服务端的连接

服务端返回ACK(第一次SYN的应答)和SYN,申请建立服务端到客户端的连接

客户端收到数据,状态置为ESTABLISHED,表示客户端到服务端连接建立完成,并且发送ACK(第二次SYN的应答),服务端收到数据,状态置为ESTABLISHED,表示服务端到客户端的连接建立完成

四次挥手

image.png


说明:关闭的时候服务端申请关闭或者客户端申请关闭都可以


客户端发送FIN到服务端,申请关闭客户端到服务端的连接

服务端收到FIN状态置为CLOSE_WAIT,并返回ACK应答(这个动作是系统实现TCP协议栈默认执行的,不需要程序来调用代码)

服务端发送FIN到客户端,申请关闭服务端到客户端的连接(程序手动调用socket.close发送)

客户端收到FIN返回ACK应答,并进入TIME_WAIT时间等待状态,客户端等待一段时间后,状态置为CLOSED,服务端收到应答后,状态置为CLOSED

思考:


为什么服务端不将ACK和FIN合并一起发送,形成三次挥手呢?

答:因为服务端状态置为CLOSED_WAIT说明服务端准备关闭连接,但是服务端可能还在继续发送数据,得处理完之前的数据,还可以执行一些关闭连接前的工作,如消耗资源等 ,所以是先给客户端发送应答,再处理完数据再向客户端发送FIN申请关闭连接


为什么客户端要等待一段时间状态才置为CLOSED,而不之间将状态置为CLOSED?

答:如果客户端给服务端的ACK丢包后,服务端得重新给和客户端发送FIN,此时客户端得给服务端应答,所以此时状态不能置为CLOSED,得等待一段时间确保服务端收到客户端的应答


2.1.4 流量控制

接收端主机处理数据的速度有限,如果发送端发送数据太快,导致接收端缓冲区被填满,这时,发送端继续发送数据的话就会造成丢包,继而引起丢包重传等一些列连锁反应,因此TCP协议根据接收端接收数据的能力,来决定发送端发送数据的速度,这个机制就叫作流量控制


接收端将自己剩余缓冲区大小存入TCP头部中的“16位窗口大小”字段 ,通过ACK通知发送端

窗口大小越大,说明网络吞吐量越高

发送端根据接收到这个窗口的大小,控制自己的发送速度

如果接收缓冲区满了,就会将窗口设置为0,这时,发送端不在发送数据,而是定期的发送一个窗口探测数据段,让接收端将窗口大小告诉发送端

2.1.5 拥塞控制

刚开始,发送端网络状况不明,如果贸然发送大量数据,就会造成大量丢包,所以TCP协议引入慢启动的方式,先发少量数据探探路,再决定按照多大速度发送数据


此处引入拥塞窗口,刚开始时,拥塞窗口设置为1,每收到一个ACK时,拥塞窗口加1,每次发送数据的时候,拥塞窗口和流量窗口的较小的值作为实际发送的窗口,即滑动窗口的大小


注意:上述增长方式是指数级别的,“慢启动”只是开始时慢,但是增长速度非常迅速


拥塞窗口变化的方式


为了不增长那摩快,引入一个慢启动的阈值,当拥塞窗口的大小超过了这个阈值,不在按照指数方式增长,而是按照线性方式增长,如下图所示:

image.png


开始时,慢启动的阈值为窗口的最大值

网络拥塞时,拥塞窗口置1,慢启动阈值变为拥塞窗口/2,重新开始增长


2.2 效率机制

2.2.1 滑动窗口

前面的确认应答机制指出,对每一个发送的数据都对应有一个ACK确认应答,这样采取一发一收的方式有一个很大的缺点就是效率太差,为了提高效率采用滑动窗口,即一次性发送多个数据

image.png


窗口大小:指无需等待而可以继续发送数据的最大值,上图的窗口大小为4000个字节(四个段)

具体如何设置窗口大小:min(流量窗口的大小,拥塞窗口的大小)

窗口如何滑动:接收到的ACK下一个是n,滑动到n-1的位置

操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答,只有应答过的数据才能从缓冲区中删掉


如果出现了丢包,如何确保可靠传输?


情况一:数据已经收到,返回的ACK应答丢包

image.png


这种情况下,部分ACK丢了不要紧,因为可以通过后续的ACK进行确认


情况二:发送数据的时候就已经丢包

微信图片_20221030151855.png


说明:


当1001~2000这段报文丢失后,发送端一直会收到1001这样的ACK

如果发送端主机连续三次收到相同的ACK如1001应答,那发送端主机就会重新发送1001~2000数据

此时,接收端收到1001~2000数据后,再次返回的ACK应答就是7001了,因为2001~7000数据都已经接收到了,被放到接收端操作系统内核的接收缓冲区了

这种机制,即时不超时也会发生重传,称作“高速重发控制”也叫“快重传机制”


2.2.2 延迟应答

如果接收端主机接收到数据时,立刻返回ACK应答,这时候返回的流量窗口就比较小,但是流量窗口越大,网络吞吐量越大,传输效率就越高,所以等待一部分时间,待接收端处理完一部分数据 ,就可以将流量窗口设置为大一点的值,这样网咯吞吐量大,效率高


延迟是为了高吞吐量,但是也不能无限延迟


数量限制,每隔n个包就应答一次

时间限制,超过最大延迟时间,就应答一次

具体的数量和时间,不同操作系统有差异,一般n取2,超时时间取200ms


2.2.3 捎带应答

服务端接收到客户端的消息后,要返回一个ACK有时候可能需要返回一个响应,此时ACK可以搭载顺风车,和响应合并为一个数据返回,不用再将ACK和响应数据分开发送


3. 粘包问题

TCP是面向字节流的,可以多次的接收和发送,对于应用层来说,一连串的字节数据,不知道从哪到哪算一个完整的应用层数据包,对应发送多少次算一个应用层完整格式的数据,和接收多少次算一个应用层完整格式的数据就不知道了


如何解决粘包问题?明确包的边界


对于定长的包,每次都按照固定大小读取即可

对于变长的包,可以在包与包之间明确分隔符(应用协议,程序员自己定,只要保证分隔符和正文不起冲突即可)


4. TCP的异常情况

进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没有什么区别

机器重启:和进程终止的情况相同

机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了就会进行reset,即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在,如果对方不在,也会把连接释放

另外,应用层的某些协议,也有一些这样的检测机制,例如HTTP长连接中,也会定期检测对方的状态,例如QQ,在QQ断线之后,也会定期尝试重新连接


5. TCP协议特点总结

有连接:通过三次握手建立连接后才可接发数据,TCP协议是全双工的,即每端既可以发也可以收

可靠传输:网络数据传输是一跳一跳的,经过路途中的设备可能发生数据丢失,可靠传输是可能发生数据丢失但有机制保证对方能接收到

面向字节流:可以多次的收发数据(连接没有关闭时,可以多次的接收和发送数据)

有接收缓冲区和发送缓冲区:发送数据时,是先写到发送缓冲区,再刷新缓冲区(flush)

大小不受限制:多次的收发数据,每次的数据可以很大


6. 基于TCP的应用层协议

HTTP

HTTPS

SSH

Telnet

FTP

SMTP

也包括自己写TCP程序时自定义的应用层协议  


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
打赏
0
0
0
0
4
分享
相关文章
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
75 18
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
107 22
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
140 12
掌握网络通信协议和技术:开发者指南
本文探讨了常见的网络通信协议和技术,如HTTP、SSE、GraphQL、TCP、WebSocket和Socket.IO,分析了它们的功能、优劣势及适用场景。开发者需根据应用需求选择合适的协议,以构建高效、可扩展的应用程序。同时,测试与调试工具(如Apipost)能助力开发者在不同网络环境下优化性能,提升用户体验。掌握这些协议是现代软件开发者的必备技能,对项目成功至关重要。
智能体竟能自行组建通信网络,还能自创协议提升通信效率
《一种适用于大型语言模型网络的可扩展通信协议》提出创新协议Agora,解决多智能体系统中的“通信三难困境”,即异构性、通用性和成本问题。Agora通过标准协议、结构化数据和自然语言三种通信格式,实现高效协作,支持复杂任务自动化。演示场景显示其在预订服务和天气预报等应用中的优越性能。论文地址:https://arxiv.org/pdf/2410.11905。
125 6
Golang 实现轻量、快速的基于 Reactor 模式的非阻塞 TCP 网络库
gev 是一个基于 epoll 和 kqueue 实现的高性能事件循环库,适用于 Linux 和 macOS(Windows 暂不支持)。它支持多核多线程、动态扩容的 Ring Buffer 读写缓冲区、异步读写和 SO_REUSEPORT 端口重用。gev 使用少量 goroutine,监听连接并处理读写事件。性能测试显示其在不同配置下表现优异。安装命令:`go get -u github.com/Allenxuxu/gev`。
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
170 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
TCP报文格式全解析:网络小白变高手的必读指南
本文深入解析TCP报文格式,涵盖源端口、目的端口、序号、确认序号、首部长度、标志字段、窗口大小、检验和、紧急指针及选项字段。每个字段的作用和意义详尽说明,帮助理解TCP协议如何确保可靠的数据传输,是互联网通信的基石。通过学习这些内容,读者可以更好地掌握TCP的工作原理及其在网络中的应用。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问