TCP的核心特性
面向连接
三次握手建立连接:通信前需通过SYN/SYN-ACK/ACK三次交互确认双方存在且可通信,确保连接可靠性。
四次挥手终止连接:通过有序的FIN/ACK交互安全关闭连接,避免数据丢失或状态混乱。
可靠传输
序列号与确认应答(ACK):每个数据包分配唯一序列号,接收方通过ACK确认已收到的数据,丢失时触发重传。
超时重传(RTO):发送方未收到ACK时,根据往返时间(RTT)动态计算超时时间,重新发送数据。
快速重传(Fast Retransmit):收到3个重复ACK时,立即重传丢失的数据包(无需等待超时)。
流量控制
滑动窗口(Sliding Window):接收方通过窗口大小(Window Size)告知发送方剩余缓冲区空间,避免发送过快导致接收方溢出。
零窗口探测:当接收窗口为0时,发送方定期发送探测包,确认接收方是否恢复接收能力。
拥塞控制
慢启动(Slow Start):初始时以指数增长发送数据,快速探测网络带宽。
拥塞避免(Congestion Avoidance):达到阈值后线性增长,避免触发拥塞。
快速恢复(Fast Recovery):收到3个重复ACK时,减半拥塞窗口并重传,快速恢复传输。
拥塞算法:包括Reno、Cubic、BBR等,优化不同网络场景下的性能。
全双工通信
连接建立后,双方可同时发送和接收数据(如客户端上传文件的同时下载数据)。
字节流服务
TCP将应用层数据视为无边界的字节流,不保留消息边界(需应用层协议如HTTP自行处理分帧)
tcp报文结构
TCP报文(Segment)由首部和数据部分组成,首部固定20字节(可选部分可扩展至60字节)
接口情况
序列号
数据包在字节流中的起始位置(初始序列号ISN随机生成)
确认号
期望接收的下一个序列号(ACK=1时有效)
首部长度
首部占32位字的数量(最小5,最大15)
标志位
URG/ACK/PSH/RST/SYN/FIN(控制连接状态或数据传输)
紧急指针
仅当URG=1时有效,指向紧急数据的末尾
选项
支持MSS(最大段大小)、窗口缩放、时间戳等扩展功能
TCP连接中标志位
TCP连接中标志位的意义<br>
TCP(传输控制协议)的标志位(Flags)位于TCP首部的控制位字段(6位),用于控制连接状态、数据传输方式或处理特殊场景
URG(Urgent Pointer Valid,紧急指针有效)
作用:标识紧急数据(需优先处理的数据)是否有效。
使用场景:
当发送方有紧急数据(如中断命令、实时控制信息)需要立即处理时,设置URG=1。
紧急数据位于普通数据流的末尾,通过紧急指针(Urgent Pointer)字段指示其偏移量(从序列号开始的字节位置)。
示例:
客户端发送URG=1, seq=100, ack=200, Urgent Pointer=5,表示序列号100开始的5字节数据为紧急数据,接收方应优先处理。
ACK(Acknowledgment,确认号有效)
作用:标识确认号(Acknowledgment Number)字段是否有效。
使用场景:
除三次握手的第一个SYN包外,所有TCP报文通常设置ACK=1,表示确认已收到的数据。
确认号为期望接收的下一个序列号(即已成功接收的最后一个序列号+1)。
示例:
服务器回复SYN=1, ACK=1, seq=y, ack=x+1,表示已收到客户端的SYN包(序列号x),并同意建立连接。
PSH(Push Function,推送数据)
作用:要求接收方立即将数据推送至应用层,而非等待缓冲区填满。
使用场景:
发送方希望接收方尽快处理数据(如交互式应用中的即时响应)。
通常由发送方设置PSH=1,接收方收到后立即将数据交给上层协议(如应用程序)。
示例:
用户按下回车键后,客户端发送PSH=1, ACK=1的报文,确保服务器立即处理输入。
RST(Reset Connection,重置连接)
作用:强制终止当前连接,通常用于异常情况(如端口未监听、连接超时、违反协议规则)。
使用场景:
接收方收到无法处理的报文(如序列号错误、端口未开放)。
主动关闭连接的一方发现异常(如重复收到FIN包)。
防火墙或中间设备主动断开连接。
特点:
发送RST=1的报文后,连接立即终止,无需四次挥手。
接收方收到RST后,会抛出Connection reset by peer错误。
示例:
客户端访问未监听的端口时,服务器返回RST=1, ACK=1的报文。
SYN(Synchronize Sequence Numbers,同步序列号)
作用:用于建立TCP连接,同步双方的初始序列号(ISN)。
使用场景:
三次握手的第一步:客户端发送SYN=1, seq=x的报文,表示请求建立连接。
服务器回复SYN=1, ACK=1的报文,表示同意连接并同步自己的序列号。
特点:
SYN包会消耗一个序列号(即seq=x占用一个字节的序列号空间)。
初始序列号(ISN)是随机生成的,避免旧连接的重放攻击。
示例:
客户端:SYN=1, seq=1000
服务器:SYN=1, ACK=1, seq=2000, ack=1001
FIN(Finish Connection,结束连接)
作用:用于正常终止TCP连接,表示发送方已无数据需要发送。
使用场景:
四次挥手的第一步:主动关闭方发送FIN=1, seq=u的报文。
被动关闭方回复ACK=1后,可继续发送数据(半关闭状态),直至自己也发送FIN包。
特点:
FIN包也会消耗一个序列号(即seq=u占用一个字节的序列号空间)。
连接终止需双方均发送FIN包(全关闭状态)。
示例:
客户端:FIN=1, seq=3000
服务器:ACK=1, ack=3001
(服务器处理完数据后)
服务器:FIN=1, seq=4000
客户端:ACK=1, ack=4001
标志位组合使用
三次握手(SYN+ACK)
客户端:SYN=1, seq=x
服务器:SYN=1, ACK=1, seq=y, ack=x+1
客户端:ACK=1, seq=x+1, ack=y+1
数据传输(PSH+ACK)
客户端:PSH=1, ACK=1, seq=100, ack=200, data="Hello"
服务器:ACK=1, seq=200, ack=105(确认收到5字节数据)
异常终止(RST)
客户端:RST=1, seq=500, ack=600(强制断开连接)
正常终止(FIN+ACK)
客户端:FIN=1, ACK=1, seq=700, ack=800
服务器:ACK=1, seq=800, ack=701
TCP的11个状态<br>
状态信息
CLOSED:初始状态,表示没有连接存在。
LISTEN:服务器端等待连接的状态。服务器通过listen()函数进入此状态,准备接受客户端的连接请求。
SYN_RCVD:收到客户端的SYN(同步序列号)包后的状态。表示服务器已收到连接请求,正在等待确认。
SYN_SENT:客户端发送SYN包后等待服务器确认的状态。客户端通过connect()函数发送SYN包,进入此状态。
ESTABLISHED:连接建立完成的状态。表示客户端和服务器之间可以进行数据传输。
CLOSE_WAIT:服务器端收到客户端的关闭连接请求(FIN包)后进入的状态。表示服务器已收到关闭请求,但仍有数据需要发送或处理。
LAST_ACK:服务器端发送完所有数据并发送FIN包后等待客户端确认的状态。
FIN_WAIT_1:客户端主动关闭连接时,发送FIN包后等待服务器确认的状态。
FIN_WAIT_2:客户端收到服务器的ACK确认后进入的状态,等待服务器发送FIN包。
CLOSING:双方同时关闭连接时的一种特殊状态。当客户端和服务器几乎同时发送FIN包时会出现此状态。
TIME_WAIT:客户端收到服务器的FIN包并发送ACK确认后进入的状态。客户端在此状态等待一段时间(通常为2MSL,最大报文段生存时间的两倍),以确保服务器收到ACK确认。
状态流转
appl: passive open:应用程序执行被动打开操作,服务器进入LISTEN状态。
appl: active open:应用程序执行主动打开操作,客户端发送SYN包,进入SYN_SENT状态。
appl: send data:在ESTABLISHED状态下,应用程序可以发送数据。
appl: close:应用程序关闭连接的操作。客户端或服务器发送FIN包,触发状态转换。
recv: SYN:收到SYN包。服务器在LISTEN状态下收到SYN包进入SYN_RCVD状态;客户端在发送SYN包后收到服务器的SYN包(实际是SYN+ACK包,但图中简化表示)会进入ESTABLISHED状态(通过发送ACK确认后)。
recv: ACK:收到确认包(ACK)。用于确认之前发送的SYN或FIN包。
recv: FIN:收到关闭连接请求(FIN包)。触发接收方进入相应的关闭状态。
send: SYN:发送SYN包,用于建立连接。
send: SYN, ACK:同时发送SYN和ACK包,用于确认收到SYN包并同意建立连接。
send: ACK:发送确认包,确认收到数据或关闭请求。
send: FIN:发送关闭连接请求(FIN包)。
send: :在某些状态下,不需要发送数据,如从TIME_WAIT状态转换回CLOSED状态时。
timeout:超时事件。例如在SYN_RCVD状态下超时未收到ACK确认,会返回到LISTEN状态;在TIME_WAIT状态下等待2MSL时间后,超时转换回CLOSED状态。
转换类型说明
normal transitions for client:客户端的正常状态转换路径。
normal transitions for server:服务器的正常状态转换路径。
state transitions taken when application issues operation:应用程序执行特定操作(如打开、关闭连接)时触发的状态转换。
state transitions taken when segment received:收到特定报文段(如SYN、ACK、FIN)时触发的状态转换。
what is sent for this transition:在状态转换过程中发送的报文段。
TCP性能优化技术
1. Nagle算法
目的:减少小数据包数量,降低网络拥塞。
原理:合并多个小数据包,仅当收到ACK或缓冲区满时发送。
2. 延迟确认(Delayed ACK)
目的:减少ACK包数量,提升吞吐量。
原理:接收方等待一段时间(如40ms)或积累足够数据后再发送ACK。
3. 选择性确认(SACK)
目的:精准重传丢失的数据包,避免重复发送已接收的数据。
原理:在ACK中携带已接收的连续数据块范围(如SACK: 100-200, 300-400)。
4. 时间戳选项(Timestamp)
目的:计算RTT(往返时间),优化超时重传和拥塞控制。
原理:发送方记录发送时间,接收方返回时间戳用于计算延迟。
TCP的局限性
头部开销大:20字节首部(UDP仅8字节),不适合传输小数据。
连接建立慢:三次握手需1.5个RTT,延迟敏感场景(如游戏、视频)可能选择UDP。
状态维护复杂:需跟踪序列号、窗口、拥塞状态等,资源消耗较高。