目录
一、TCP协议概念
TCP(Transmission Control Protocol 传输控制协议)是互联网传输层的核心协议,核心是提供面向连接、可靠、基于字节流的端到端的传输服务,运行在 IP 协议之上,适配Web、邮件、文件传输等对可靠性要求高的场景。
二、TCP协议端格式
- **16位源端口号:**标识发送方的应用进程
- **16位目的端口号:**标识接收方的应用进程
- **32位序号:**标识当前报文段第一个字节的编号,确保数据按序重组
- **32位确认序号:**接收方收到的数据,最后一个字节序号 + 1
- **4位首部长度:**以4字节为单位,标识TCP头部总长度
- **保留6位:**预留字段
- **标志位:**控制连接与数据传输的关键标识
- **16位窗口大小:**接收方告知发送方自己的可用缓存大小,用于流量控制,存在窗口扩展 因子
- **16位校验和:**检测头部和数据的值是否传输正确
- **16位紧急指针:**当URG标志位为1时有效,指向紧急数据的末尾位置
三、TCP的核心机制
1、确认应答(保证可靠性)
TCP 实现可靠传输的最核心机制,以 主机1 和 主机2 为例,每次主机1向主机2发送消息(或主机1向主机2发送)时,接收方会先返回ack报文
在传输数据时 32位序号会对数据进行编号(给字节进行编号,连续递增),确认序号是收到的数据的序号 +1,来表示下一个数据从此编号开始
注意:
应答报文是操作系统自动回应,无需编写代码
在发送多条数据时可能会导致数据后发先至,32位序号对数据进行编号之后就可以根据确认序号来判断数据是否应该先到,这样就解决了后发先至的问题了
2、超时重传(保证可靠性)
TCP实现可靠传输的最核心机制,以 主机1 和 主机2 为例,在主机1向主机2发送消息时,经过一定的时间主机1未收到主机2传回的应答报文,主机1就会再次传输同样数据,来确保数据正常发送
注意:
在传输数据时有可能是数据未正常发送成功,也有可能是ack报文未正确返回,此类现象为**丢包现象,**这种现象在传输过程中概率发生
- 如果是数据未正常传输,发生了丢包现象,那么进行重传肯定是必要的
- 如果是ack报文丢了,那么就不应该重新传输一次数据,在发送方发送数据时,操作系统会给接收方分配一个接收缓冲区来帮助接收区接收数据,接收方会根据收到的数据序号对数据进行去重,这样就避免了一个数据多次重传问题
- 超时重传的时间间隔也不是固定的,会根据次数逐渐拉长
- 超时重传也不是无限次,再经过多次传输都没有到达,发送方会认为网络发生故障,主动放弃连接
3、连接管理(*)
连接管理分为建立连接和断开连接,是由操作系统实现的
①"三次握手"
建立连接,流程为 " 三次握手 ",网络中 " 握手 " 是给对方发送一个不包含业务数据的数据包(没有载荷)
以客户端和服务器为例,当两台设备进行连接时,其中一方发送 syn(同步报文),另一方返回 ack(应答报文),然后发送 syn (同步报文)与另一方建立连接并等待对方ack回应,只有双方都收到对方都通过 syn "通知" 后连接才建立好
注意:
第二次的syn和ack可以合为一个(时机相同),提升效率
"三次握手"意义:
- 起到 "投石问路"的作用,像地铁的早晨第一班车不载客一样,用来验证通信链路是否畅通
- 验证双方的发送和接收功能是否正常
- 一些必要的 "协商工作",比如一些参数,序号的起始值并不是从1开始,每次连接时起始值差别较大
②"四次挥手"
断开连接,流程为 "四次挥手","挥手"其实和"握手"类似,这样的操作都不包含业务逻辑(没有载荷)
以客户端和服务器为例,其中一方向对方发送 FIN(断开连接报文),另一方在收到对方发送的时候返回 ack(应答报文)并也向对方发送 FIN 进行断开连接,在收到对方的 ack 时结束
注意:
FIN 和 ACK 不可以合并为一次操作,因为要考虑具体逻辑,ack 是自动触发的
③TCP常用状态
- **LISTEN:**服务器特有的状态,服务器启动,socket 关联好端口号后,状态就是LISTEN,随时可以和客户端进行连接
- **ESTABLISHED:**客户端和服务器都会有的状态,这个状态用来表示连接已经建立好,随时可以继续网络通信
- **CLOSE_WAIT:**断开连接的时候收到 FIN 的一方,直到主动发出 FIN ,就是等待调用 close() 方法
- **TIME_WAIT:**主动断开连接的一方会有的状态,作用是等待一定时间,为了处理 "最后一个ack丢包的现象",持续一定时间后没有收到重传的FIN,那么就认为对方已经收到ack了
4、滑动窗口(提升效率)
TCP提升效率的一种手段,实质是批量发送,批量等待 ACK ,在一定程度上减少了等待 ACK 的时间,批量传输并不意味着无限大小,是根据一定的窗口向后滑动来实现批量传输
以 主机1 和 主机2 为例,如果不进行批量发送,那么每发一条数据就需要等待对方返回的ACK,如果数据多的时候,这里就需消耗不少的时间资源,而通过滑动窗口来批量发送和接收就可以省下不少的时间资源
那么在滑动窗口中丢包又该如何应对呢?
- 如果是 ACK 丢失,那么不需要做任何处理,后一个ACK可以包含前一个ACK
- 如果是进行批量传输时数据丢失,会有一个**"快速重传"机制搭配滑动窗口中的重传机制,其中一条数据丢失后,继续向后发送的数据返回的ack都是该数据的ack,连续多次都是同一个ack后,发送方就会意识到该数据丢了,然后进行重传,在重传之后不需要从丢包的数据发送ack,直接从真正发送到的位置继续进行发送即可**
5、流量控制(保证可靠性)
TCP 保证可靠性的机制,滑动窗口越大传输效率就越高,但如果传输过快,接收方处理不过来,那么就可能会直接丢包,流量控制就是对滑动窗口的大小进行控制
如何来控制?
- 接收方处理能力的衡量:通过接收缓冲区剩余空间的大小来反向限制传输速度
- 衡量之后如何通知:通过ack通知发送给对方
如果接收方满了,发送方就得停止发送,如果后续缓冲区有余位如何通知?
发送方如果未收到窗口更新的通知,那么定期会发送窗口探测包来得到窗口大小的值
6、拥塞控制(保证可靠性)
TCP 保证可靠性的手段,和流量控制类似,依据通信路径的处理能力对发送速度进行限制,刚开始是以较慢的速度进行发送,如果未发生丢包现象则加快速度
注意:
- 窗口大小不是固定值,而是**"动态变化"**的
- 窗口的大小是取拥塞窗口和流量控制窗口的较小值
拥塞窗口的变化规律曲线:
初始情况下,窗口大小是1000,等到ack回来后进行下一轮传输
- 初始情况下,窗口非常小(慢启动)
- 在达到一定阈值前窗口大小指数增长(增幅非常大)
- 当窗口大小达到阈值时变为线性增长(降低增幅,避免因增长太大丢包)
- 线性增长也会达到一定大小丢包
- 丢包后拥塞窗口进行缩小,回到阈值位置线性增长,新阈值为丢包位置的 1/2
7、延迟应答(提升效率)
TCP 提升传输效率的手段,在有限的机制下将窗口变大,将 ack 返回时间拖晚一点,应用程序可能会处理一定的数据,接下来发送的速度就会变快
8、捎带应答(配合延迟应答)
"一问一答" 是网络通信中常见模型,以客户端和服务器为例,当客户端发送请求,服务器根据请求计算响应,如果中间的计算很快可以赶上延迟应答,此时就可以将 ack 和响应结果打包成一个数据包进行发送
9、面向字节流
粘包问题
面向字节流传输的过程,可能会涉及到粘包问题,因为每个应用层数据包之间的界限2并不明显,TCP如何读取数据都可以
如何处理粘包问题:
- 引入分隔符,特殊符号作为包的开头和结束标记
- 在数据开头时,添加一个固定属性,表示数据包的长度
10、异常情况
①进程崩溃
和 "四次挥手" 完全相同,进程退出了,操作系统会自动对资源进行释放,虽然客户端退出了,但与服务器的连接还在,操作系统仍继续处理后续的挥手过程
②主机关机(正常流程)
每次关机之后,电脑会强制杀掉所有的进程,如果关机正常(需要一定时间),可以使 "四次挥手" 正常结束,但如果关机快了,可能会导致进程未处理完,服务器未收到对方的ack 就会重传 FIN ,在多次重传后未收到,服务器就会单方断开连接,后续发生什么也就不管了
③主机关机(掉电)
电源断开,导致电脑直接关机,这种情况是来不及执行 "四次挥手" 过程,分两种情况,,一种是接收方断电,一种是发送方断电
④网线断开
网线断开的情况也和主机关机(掉电)的状况相同,也分为两种
四、基于TCP应用层协议
- **HTTP(80端口):**超文本传输协议,网页浏览核心
- **HTTPS(443端口):**加密版HTTP,安全传输网页数据
- **FTP(21端口):**文件传输协议,用于文件上传下载
- **SMTP(25端口):**简单邮件传输协议,发送电子邮件
- **DNS(53端口,TCP/UDP双用):**域名解析,TCP用于主从同步
- ........
五、TCP总结
- 核心特征:面向连接、可靠传输、有序交付、字节流服务,三次握手建立连接,四次挥手断开连接
- 关键机制:确认应答、超时重传、滑动窗口、流量控制、拥塞控制
- 适配场景:对可靠性要求高,容忍延迟
- 缺点:建立连接耗时,开销略大
















