网络协议打怪升级-传输层:TCP
1.TCP是什么
TCP是一种面向连接、可靠传输、基于字节流的传输层协议,与IP协议共同组成TCP/IP协议族的基础
2.TCP的核心概念
2.1.三次握手与四次挥手
此处应与UDP协议作为比较,TCP协议通过面向连接、顺序传输、流量控制等特性,保证该协议的数据传输的高可靠性。
- 面向连接
- TCP是基于连接进行数据传输的,开始数据传输之前,需要通过三次握手建立TCP连接;数据传输完成后,通过四次挥手结束TCP连接,释放资源
- 握手与挥手时的标识位定义
| 标识位 | 含义 | | — | — | | SYN | 发起建立连接请求,携带初始化序列号 | | ACK | 确认收到数据,携带确认号ACK=n,标识确认收到”n-1” | | SEQ | 标识数据段的序列号,用于顺序重组,保证顺序一致 | | FIN | 标识对方已经没有数据要发送了,请求关闭连接 |
- 三次握手
1 2 3
1-客户端发送SYN=1,ACK=0,SEQ=x,请求建立连接,发送序号为x 2-服务端收到请求,回复SYN=1,ACK=1,SEQ=y,ACK=x+1,服务端同一连接,发送初始序列号y,确认客户端的x 3-客户端收到服务端的消息,回复ACK=1,SEQ=x+1,ACK=y+1,确认连接建立,发送确认号y+1
为什么是三次握手?不是两次或四次?
1 2 3 4
1-如果是两次握手,只能收到ACK=x+1和ACK=1,不能没有收到ACK=y+1,不能确认服务端的发送能力 2-可靠性保证,如果只有两次握手,若服务端收到延迟到达的SYN时,会建立连接,然而此时是不需要建立连接的(连接已建立或已废弃), 因此,需要第三次握手来保证服务端发送的SYN-ACK是针对当前连接的。 3-三次握手已足以分别验证客户端与服务端的发送与接收能力,不需要再多一次握手造成资源浪费。
- 四次挥手
由于TCP是全双工协议(客户端和服务端都可以发送、接收数据),因此,需要四次挥手保证双方有序完成传输并释放资源。
1 2 3 4
1-客户端发送FIN,表示传输已完成,并将自己的状态设置为FIN_WAIT_1 2-服务端收到FIN,发送ACK给客户端确认收到的FIN,此时服务端状态为CLOSE_WAIT,客户端状态变为FIN_WAIT_2 3-服务端继续发送剩余数据(如果有),然后向客户端发送FIN,表示自己的数据已传输完成,此时服务端状态变为LAST_ACK 4-客户端收到FIN,发送ACK确认已收到服务端的结束信号。然后客户端与服务端都关闭连接
- TCP是基于连接进行数据传输的,开始数据传输之前,需要通过三次握手建立TCP连接;数据传输完成后,通过四次挥手结束TCP连接,释放资源
2.1.可靠传输
TCP传输是可靠的,可靠性的核心在于,即使网络出现丢包、乱序、重复或延迟,TCP也能确保数据按序无误交付,TCP通过以下机制保证其可靠性。
- 1.序列号(SEQ):
- 特性:TCP将数据视为字节流,每个字节会分配一个序列号,既
检测丢包或重复包
,也能支持乱序重组
- 实现原理:
- 三次握手中,双方交换初始序列号,随机生成
x
或y
- 传输过程中,每个数据端(Segment)携带
段中第一个字节的序列号(Sequence Number)
与段中字节数(Length)
- 接收方接收到消息后,会根据序列号重新排序并缓存,若缺少某段(如2000-2999),等待重传
- 三次握手中,双方交换初始序列号,随机生成
- 示例:
- 发送方发送1:SEQ=1000,LEN=500;2:SEQ=1500,LEN=500
- 如果接收方先收到2,接收方缓存,并等待1到达
- 可靠性贡献:
- 序列号确保数据按序交付,重复包被丢弃,缺失包被重发
- 特性:TCP将数据视为字节流,每个字节会分配一个序列号,既
- 2.确认应答(ACK):
- 特性:接收方(客户端与服务端)通过ACK(确认应答)通知发送方(已正确接收数据&&等待发送方发送的数据)序列,驱动后续过程
- 示例:
- 收到SEQ=1000,LEN=500,接收方回复ACK=1500,表示已收到1500之前,等待1500及之后
- 若一段时间后客户端没有收到ACK=1500,重传数据包
- 若服务端又收到数据包,丢弃并重新回复ACK=1500
- 累计确认
- 1-若前面还有包没收到,比如SEQ=500,LEN=500还未收到,则不回复ACK=1500
- 2-回复ACK=1500表示已收到序列号为1500之前的所有数据
- 捎带确认:
- ACK通常随数据一起发送,减少开销
- 可靠性贡献:
- 确认应答让发送方直到哪些数据已送达,触发重传或继续发送
- 3.重传机制:
- 特性:处理数据丢失或错误(校验和失败),确保所有数据最终到达
- 实现原理:
- 超时重传:
1 2 3
1-发送方为每个段(Segment)设置超时时间RTO(Retransmission Timeout),基于往返时间RTT动态计算 2-若超时未收到ACK,重发该段 3-连续超时后,RTO翻倍,防止网络拥堵
- 快速重传:
1 2 3 4 5
1-接收方接收到乱序段后,立即发送ACK 2-发送方收到三个连续ACK后,立即认为ACK确认的段丢失 举例: 发送方发送SEQ=1000,1500,2000,2500;其中1000丢失, 接收方收到1500后,发现1000没有收到,回复ACK=1000表示期望确认SEQ=1000的数据
- 选择性确认:
1 2
可选机制(RFC 2018),接收方报告已收到但非连续的段 示例:收到1000-1499和2000-2499,SACK通知2000-2499,发送方只重传1500-1999
- 超时重传:
- 可靠性贡献:
- 重传确保丢失或错误的数据被重新发送,结合序列号和ACK实现数据段无遗漏
- 4.滑动窗口:
- 特性:
- 允许多个数据段同时发送,而无需等待每个段的ACK,提高传输效率
- 控制流量,避免接收方缓冲区溢出
- 实现原理:
- 窗口概念:
1 2 3
发送窗口:发送方可发送但未确认的字节范围 接收窗口:接收方可接受的字节范围(基于接收方缓冲区大小) 窗口大小由接收方在ACK中通过Window Size字段通知
- 滑动机制:
1 2 3 4 5 6
发送方发送窗口内的段,收到ACK后向前滑动窗口 示例: 1.初始:发送窗口1000-1999(大小1000) 2.发送:SEQ=1000,LEN=500 3.收到:ACK=1500,Window=1000 4.窗口前滑,新窗口1500-2499
- 零窗口处理:
1 2
若接收方缓冲区满,回复window=0,发送方停止发送 接收方回复后发送窗口更新(Window Update)
- 流量控制:窗口大小动态调整,防止发送方过快压垮接收方
- 窗口概念:
- 可靠性贡献:
- 滑动窗口通过批量发送和确认提高效率,同时也避免接收方过载而压垮接收方
- 特性:
- 5.拥塞控制:
- 特性:
- 防止发送方过快发送数据导致数据拥堵(如路由器缓冲区溢出)
- 在可靠性基础上优化网络性能
- 实现原理:
- TCP使用拥塞窗口(Congestion Window,cwnd)控制发送速率,与滑动窗口相组合,取两者最小值作为实际发送窗口,既优化网络性能也保证了可靠性
- 慢启动:
1 2 3 4 5 6 7
初始cwnd较小(如1),每收到一个ACK,cwnd翻倍,直到达到慢启动阈值,或检测到拥堵 示例: 1-初始cwnd=1。 2-收到一个ACK,cwnd=2。 3-收到一个ACK,cwnd=4。 ... n-达到慢启动阈值OR检测到拥堵,cwnd不再程指数级增长,转为每次+1的线性增长,若拥堵可能会降低cwnd
- 拥塞避免: 超过慢启动阈值后,cwnd不再指数级增长,转为每次+1的线性增长,避免激进发送导致网络拥堵
- 快速回复: 检测到丢包(三个重复ACK)后:cwnd = cwnd/2 + 3,并且进入拥塞避免,不再指数级上升cwnd
- 超时重传: 若超时(未收到ACK),认为网络已经进入严重堵塞,此时慢启动阈值被设置为cwnd/2,并重新开始慢启动,即cwnd = 1
- 可靠性贡献:
- 拥塞控制动态调整发送频率,减少丢包,保证可靠性的基础上也优化了网络性能
- 特性:
- 6.综合:可靠性的整体保障
- 序列号+确认应答:按序发送,无重复、无丢失
- 重传:弥补网络不可靠性
- 滑动窗口+拥塞窗口:尽量保证网络效率的情况下提高数据传输的可靠性
2.2.TCP的传输方式
TCP是基于字节流的传输,将应用层的数据打包成报文段,并交给网络层(IP层)封装成包。TCP不关心数据边界,只保证字节的顺序和可靠性
什么是
基于字节流
的传输? 所谓’字节流’是指应用层发送给TCP的数据被看作一串没有边界
的字节序列,TCP不关心数据的消息边界
,TCP只管把这些字节分段打包为字节段
,并发送出去- 1.分段
- 当应用层一次性传输的数据过大,大于一个窗口可传递的值,TCP会自动把它且分为多个TCP报文段,每个报文段包含
段头
与段数据
- 通常来说,TCP段头长度为
20Byte
,TCP段数据长度为1460Byte
- 当应用层一次性传输的数据过大,大于一个窗口可传递的值,TCP会自动把它且分为多个TCP报文段,每个报文段包含
- 2.打包/合并包
- 如果应用层发送的数据很小,TCP可能把多个应用层数据合并
2.3.错误校验
TCP使用一种叫做校验和
的机制来检测数据在传输过程中是否发生损坏或丢失,实现简单,不校验错误,只发现错误
- 校验范围
- 【伪首部】+【TCP头部】+【TCP数据】
- 【伪首部】指IP层的信息,如源IP、目标IP、协议号、TCP长度等,也就是说,校验和的计算不仅仅计算TCP层的数据,还计算了IP层的数据
- 计算步骤
- 把校验范围(【伪首部】+【TCP头部】+【TCP数据】)分为16位一组
- 把16位的数值全部相加
- 得到的结果再取反
- 最终得到校验和
- 当接收方接收到数据时,接收方对内容进行计算得到校验和,如果不等于报文中的校验和,说明数据损坏,TCP会丢弃报文段,并触发重传机制
- 网络攻击者可以伪造TCP报文并计算校验和,TCP本身不能对抗此种恶意攻击,只能检测传输过程中的错误
3.TCP的使用场景
| 应用 | 描述 | | — | — | | HTTP/HTTPS | - | | SSH/Telnet | 远程命令行连接 | | FTP | 文件传输 | | SMTP | 邮件发送 | | 数据库连接 | 如MySQL、PostgreSQL等 |
4.总结
TCP是面向连接、可靠传输、基于字节流的协议。它通过三次握手建立连接,四次挥手断开连接。
由于序列号、应答确认、重传机制、滑动窗口、拥塞控制等机制的存在,既保证了TCP连接的高可靠性,也兼顾了网络性能
对于应用层传递下来的较大的包或较小的包,TCP有分段机制和打包机制,旨在提高传输效率,并保证包不丢失
校验和作为TCP报文的其中一个字段,用于保证报文传输过程中数据不出现错误,但校验和不能检验出恶意包,只能发现网络传输中的包错误,当发现错误时,通过重传机制通知发送方重新发送报文