TCP协议(一)
一、TCP协议,主要特点二、TCP协议段格式三、确认应答机制1、基本流程2、作用3、示意图4、序列号四、超时重传机制1、介绍2、重传超时时间3、往返时间4、平滑往返时间5、系统实现6、数据丢失重传7、确认应答丢失重传五、连接管理机制1、示意图2、TCP连接建立(三次握手)3、TCP连接关闭(四次挥手)(1)半关闭状态4、TCP状态转换5、MSL7、SYN_SENT、RECV和ESTABLISHED
·
一、TCP协议
1、介绍
- TCP协议,全称Transmission Control Protocol,即传输控制协议,在OSI参考模型中工作于传输层,处于IP协议的上一层。它定义了两台计算机之间进行可靠的传输而交换的数据和确认信息的格式,以及计算机为了确保数据的正确到达而采取的措施。
- TCP协议通过面向连接、端到端和可靠的数据包发送,确保数据在传输过程中的可靠性、有序性和完整性。
- 在建立TCP连接时,需要进行三次握手过程;在断开TCP连接时,需要进行四次挥手过程。
- TCP是一种基于字节流的传输协议,它将数据视为连续的字节序列进行传输。这种特性使得TCP可以更加灵活地处理数据,不受数据块大小的限制。在TCP通信中,发送方将数据分割成若干个数据块(TCP报文段),每个数据块包含一个序列号来标识数据在字节流中的位置。接收方再根据序列号将这些数据块按顺序重组成完整的字节流。
2、主要特点
- 面向连接:TCP协议在传输数据之前,需要建立连接,确保双方都准备好进行数据交换。这种连接是可靠的,一旦建立,就可以保证数据的有序传输。
- 可靠性:TCP协议通过序列号、确认应答、超时重传、流量控制和拥塞控制等机制,确保数据包的可靠传输。即使数据包在传输过程中丢失或损坏,TCP协议也能通过重传机制恢复数据。
- 有序性:TCP协议保证数据包的顺序,即使它们通过网络到达接收方的顺序不同,TCP也会重新排序,确保数据的顺序与发送时一致。
- 全双工通信:TCP协议允许双方在任何时候都能发送数据,为此TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。
- 流量控制:TCP协议通过滑动窗口机制进行流量控制,防止发送方发送数据过快导致接收方来不及处理。
- 拥塞控制:TCP协议能够感知网络拥塞,并相应地调整传输速率,以避免网络过载。
二、TCP协议段格式
1、示意图
2、介绍
- 源端口(Source Port):16位,表示发送端进程的端口号,用于标识发送端的应用进程。
- 目标端口(Destination Port):16位,表示接收端进程的端口号,用于标识接收端的应用进程。
- 序号(Sequence Number):32位,用于标识发送端发送的数据的序号,确保数据的顺序性和完整性。在建立连接时,计算机会随机生成一个随机数作为初始序号。
- 确认序号(Acknowledgment Number):32位,用于标识接收端已经接收到的数据的序号。发送端可以根据确认序号判断数据是否已经被接收端正确接收。
- 数据偏移(Data Offset):也称为首部长度(Header Length),4位,以4字节为单位表示TCP头部的长度。由于TCP报头的范围为20 ~ 60字节,因此4位数据偏移的范围就是5 ~ 15(即20 ~ 60字节除以4)。
- 保留位(Reserved):6位,目前未使用,通常置为0。
- 控制位(Control Bits):6位,包括多个标志位,用于控制TCP连接的状态和数据传输的行为。具体包括:
标志位 | 行为 |
---|---|
URG(Urgent Pointer) | 紧急指针是否有效,置1表示紧急数据存在,需要优先处理 |
ACK(Acknowledgment) | 确认号是否有效,置1表示确认应答有效 |
PSH(Push) | 提示服务端立刻将TCP缓冲区的数据读走 |
RST(Reset) | 对方要求重新建立连接,置1表示连接需要重置。携带RST标识的称为复位报文段 |
SYN(Synchronize) | 请求建立连接,携带SYN标识的称为同步报文段。在三次握手过程中,SYN用于发起连接请求 |
FIN(Finish) | 通知对方本端将断开连接,携带FIN标识的称为结束报文段。在四次挥手过程中,FIN用于发起断开连接的请求 |
- 窗口大小(Window Size):16位,用于流量控制,表示接收端允许发送端发送的数据量的大小。发送端应根据接收端的窗口大小来控制发送数据的速率,以避免接收端缓冲区溢出。
- 校验和(Checksum):16位,用于校验TCP头部和数据的完整性。发送端会计算TCP头部和数据的校验和,并将其放置在校验和字段中。接收端在接收到数据后,会重新计算校验和,并与发送端的校验和进行比较,以判断数据是否在传输过程中发生错误。
- 紧急指针(Urgent Pointer):16位,用于指示紧急数据在TCP报文段中的位置。当URG标志位置1时,紧急指针才有效。紧急数据通常用于传输需要优先处理的信息,如中断信号等。
- 选项(Options):长度可变,用于扩展TCP协议的功能。选项字段可以包含多个选项,每个选项都有其特定的格式和含义。常见的选项包括最大报文段长度(MSS)、窗口扩大因子、时间戳等。
- 数据:即有效载荷,它是TCP报文段中实际传输的数据部分。在TCP协议中,有效载荷的长度是可变的,取决于发送端和接收端的协商以及网络状况等因素。
三、确认应答机制
1、基本流程
- 发送数据:当发送方要向接收方发送数据时,它会在TCP头部中的序列号字段中记录当前数据报载荷中第一个字节的编号。TCP是面向字节流的,这里的编号是按照字节来编排的,每个字节都有一个独立的编号,且编号是连续且递增的。
- 接收数据:接收方在收到数据包后,会检查数据包的序列号,并根据序列号确认是否已经接收过该数据包或该数据包的部分内容。如果接收方成功接收了数据包,它会记录此次接收数据最后一个字节的编号,并准备返回确认应答。
- 发送确认应答:接收方会向发送方返回一个确认应答报文(ACK),在确认应答报文中,确认号字段会被设置为接收方期望接收的下一个数据包的序号,即接收到的最后一个字节的编号加1。这样,发送方就知道接收方已经成功接收了哪些数据,并可以根据这个信息来决定下一次发送数据的起始序列号。
2、作用
- 保证数据可靠传输:通过确认应答机制,发送方可以确保接收方已经成功接收了发送的数据。如果发送方在一定时间内没有收到接收方的确认应答,它会认为数据包丢失,并触发重传机制来重新发送数据包。
- 维持数据传输的顺序:由于TCP是面向连接的协议,它保证数据传输的顺序性。确认应答机制通过确认号字段来确保接收方按照发送方发送的顺序接收数据,从而避免了数据包的乱序问题。
3、示意图
4、序列号示意图
- 实际在TCP建立连接时会协商好起始序列号,而在后续的通信中,“序列号”是在这个起始序列号的基础上偏移。
四、超时重传机制
1、介绍
- 在TCP通信过程中,发送端每发送一个报文段,就会启动一个计时器(也称为重传定时器)并等待接收端的确认应答(ACK)。
- 如果在计时器超时之前,发送端没有收到接收端的确认应答,那么发送端就会认为该报文段已经丢失或损坏,并重新发送该报文段,直到收到确认应答为止。
2、重传超时时间
- 重传超时时间(RTO,Retransmission TimeOut)是TCP超时重传机制中的关键参数。RTO的值需要根据当前的网络状况进行动态调整。
- 如果RTO设置得过大,发送端需要经过较长时间的等待才能发现报文段丢失,这会降低连接数据传输的吞吐量。
- 如果RTO设置得过小,发送端可能会将一些延迟较大的报文段误认为是丢失,从而造成不必要的重传,浪费网络资源。
- 为了动态调整RTO的值,TCP协议使用了一种自适应算法。该算法通过监视每个连接的性能(即传输时延),推算出合适的RTO值。当连接时延性能变化时,TCP也能够相应地自动修改RTO的设定,以适应网络的变化。
3、往返时间
- 往返时间(RTT,Round Trip Time)是指数据从发送端到接收端并返回发送端所需的时间。
- TCP协议以RTT为基础,采用自适应算法来确定重传时间。然而,由于RTT对应不同报文段的往返有不同的时延,且起伏较大,因此不能直接作为重传超时的标准。
4、平滑往返时间
- 平滑往返时间(SRTT,Smoothed RTT),它是通过对多个RTT样本进行加权平均计算得到的,它能够更平滑地反映网络的当前状况。
- 每次测量到一个新的RTT样本后,都会根据平滑因子α来更新SRTT的值。平滑因子α的取值范围通常在0.8至0.9之间。
5、系统实现
- 在Linux、BSD Unix和Windows中,超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
- 如果重发一次之后,仍然得不到应答,等待2 * 500ms后再进行重传。如果仍然得不到应答,等待4*500ms进行重传,依次类推,以指数形式递增。
- 累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接。
6、数据丢失重传示意图
7、确认应答丢失重传示意图
五、连接管理机制
1、示意图
2、TCP连接建立(三次握手)
(1)过程
- 客户端发送SYN报文:客户端首先向服务器发送一个带有SYN标志位的数据包(SYN报文),其中包含了客户端的初始序列号(ISN,Initial Sequence Number)。这个数据包的作用是告诉服务器,客户端希望建立连接。
- 服务器发送SYN-ACK报文:服务器收到客户端的SYN报文后,会回复一个带有SYN和ACK标志位的数据包(SYN-ACK报文)。这个响应中,服务器确认了客户端的SYN请求(即接收到了客户端希望建立连接的请求),并指定了服务器的初始序列号(ISN)。此时,服务器也向客户端表达了希望建立连接的意愿。
- 客户端发送ACK报文:最后,客户端收到服务器的SYN-ACK报文后,会发送一个带有ACK标志位的数据包(ACK报文),表示确认了服务器的响应。在这个ACK数据包中,客户端会确认收到了服务器的SYN响应,并指定了下一个要发送的序列号。至此,三次握手完成,TCP连接建立成功,双方可以开始进行数据传输。
- 连接建立成功和上层有没有进行accept(参见网络编程套接字)操作没有关系,因为三次握手是双方操作系统自动完成的。
(2)意义
- 确认当前通信路径是否畅通。
- 验证通信双方(即客户端和服务器)的发送能力和接收能力是否正常。
- 三次握手的过程中,通信双方会协商一些必要的参数,如初始序列号、双方的发送/接受缓冲区大小等。
(3)异常
- 客户端在三次握手中,认为只要把三次握手中的第三次报文(ACK报文)发出,就认为连接建立成功。但是,服务器在收到这个报文前都不认为连接建立成功。此时,如果该报文(ACK报文)丢失且客户端开始发送数据,服务器就会发送复位请求RST重新建立连接。
- 三次握手为奇数次握手,可以确保在一般情况下,握手失败连接的成本是嫁接在客户端的。
- 当握手次数是一次时,如果客户端发送大量建立连接的请求时,服务器端也需要对这些连接进行管理,即会消耗资源。如果这些连接的恶意的,即为SYN洪水,服务器很容易被攻击。
- 当握手次数是两次时,当连接建立失败时,客户端在进行连接所需要的操作过程中,不会消耗过多的资源。即不会真正建立连接。而服务器会认为连接已经建立成功,而实际此连接建立失败,但是资源已经分配出去了。如果要释放连接需要等待一段时间,这期间会导致这部分资源被浪费。即连接建立失败的代价是服务器承受的。
3、TCP连接关闭(四次挥手)
(1)过程
- 主动关闭方发送FIN报文:主动关闭方(可以是客户端,也可以是服务器)发送一个带有FIN标志位的数据包(FIN报文),表示数据发送完毕,请求关闭连接。此时,主动关闭方不再发送数据,但仍能接收数据。
- 被动关闭方发送ACK报文:被动关闭方(即接收FIN报文的一方)收到FIN报文后,回复一个带有ACK标志位的数据包(ACK报文),表示确认收到了主动关闭方的关闭请求。此时,主动关闭方到被动关闭方的单向连接就释放了,TCP连接进入半关闭状态。被动关闭方仍可以继续发送数据。
- 被动关闭方发送FIN报文:被动关闭方数据发送完毕后,也发送一个带有FIN标志位的数据包(FIN报文),表示自己也请求关闭连接。
- 主动关闭方发送ACK报文:主动关闭方收到被动关闭方的FIN报文后,回复一个带有ACK标志位的数据包(ACK报文),表示确认收到了被动关闭方的关闭请求。此时,双方都已经关闭了发送和接收通道,TCP连接完全关闭。
(2)半关闭状态
- 半关闭状态是指在一个TCP连接中,通信的一方关闭了数据的发送,但仍保持接收数据的能力。
- 半关闭为TCP连接提供了更灵活的控制方式,特别适用于客户端和服务器需要相互独立地关闭发送通道的场景。
4、TCP状态转换
状态 | 意义 |
---|---|
CLOSED | 初始状态,表示TCP连接尚未建立或已被关闭 |
LISTEN | 服务器处于监听状态,等待客户端的连接请求 |
SYN-SENT | 客户端已发送SYN报文,等待服务器的SYN-ACK报文 |
SYN-RECEIVED | 服务器已接收SYN报文,并发送了SYN-ACK报文,等待客户端的ACK报文 |
ESTABLISHED | TCP连接已建立,双方可以进行数据传输 |
FIN-WAIT-1 | 主动关闭方已发送FIN报文,等待被动关闭方的ACK报文 |
FIN-WAIT-2 | 主动关闭方已收到被动关闭方的ACK报文,等待被动关闭方的FIN报文 |
CLOSE-WAIT | 被动关闭方已收到主动关闭方的FIN报文,并发送了ACK报文,等待应用程序关闭连接 |
LAST-ACK | 被动关闭方已发送FIN报文,等待主动关闭方的ACK报文 |
TIME-WAIT | 主动关闭方已收到被动关闭方的FIN报文,并发送了ACK报文,等待2MSL(最大报文段生存时间)以确保所有迟到的数据包都被丢弃 |
5、MSL
- MSL(Maximum Segment Lifetime),即最大报文段生存时间,定义了TCP报文段在网络中的最长存活时间。在TCP/IP网络中,当一个TCP报文段被发送出去后,它会在网络中的各个节点上存放一段时间,这段时间就是MSL。
- MSL的主要功能是确保TCP连接的可靠性和稳定性,防止网络中出现环路,并可以在一定程度上影响TCP/IP网络的性能。
- MSL是一个可配置的参数,其长度可以由网络管理员根据网络的实际情况进行调整。在RFC 793(TCP的原始规范)中,建议MSL的值为2分钟。然而,在实际应用中,这个时间长度可能会有所不同,常见的时长有30秒或1分钟等。
- 如果MSL设置得太短,可能会导致TCP报文段过早地被丢弃,从而影响数据的传输;如果MSL设置得太长,则可能会增加网络的负担和延迟。
6、示意图
- 较粗的虚线表示服务端的状态变化情况。
- 较粗的实线表示客户端的状态变化情况。
- CLOSED是一个假想的起始点,不是真实状态。
7、SYN_SENT、SYN_RECV和ESTABLISHED状态
- 在Linux内核协议栈中,其为tcp的连接管理使用两个队列,分别是半连接队列和全连接队列。
- 半连接队列用来保存处于SYN_SENT和SYN_RECV状态的连接。被建立连接的一方,处于SYN_RECV半连接状态,而server端,不会长时间维护该状态。即半连接的节点,不会被长时间维护。
- 全连接队列(accpetd队列)用来保存处于ESTABLISHED状态的连接,但是应用层没有调用accept取走。
- 全连接队列的长度受到listen第二个参数backlog影响(参见网络编程套接字),当全连接队列满了的时,无法继续让半连接队列的连接的状态进入ESTABLISHED状态。
六、异常情况
1、介绍
- TCP异常情况在网络通信中时有发生,这些异常可能导致数据传输的中断、错误或延迟。
- 对TCP异常情况的处理有许多种,如抓包分析、日志分析、代码分析、性能监控、优化措施。
2、分类
(1)进程终止
- 当TCP连接中的一方进程终止时,会释放对应的PCB(Process Control Block,进程控制块)及当前对应的文件描述符。
- 进程终止会触发四次挥手断开连接,尽管进程终止,但连接并不会立即终止,而是相当于调用了套接字socket的关闭函数。
(2)机器重启
- 机器重启时,会先终止所有进程,然后进行系统重启。在重启过程中,TCP连接也会进行四次挥手断开。
- 如果机器在重启前未能及时断开TCP连接,重启后可能会收到之前连接的报文,此时会回复RST报文以重置连接。
(3)机器断电或网线断开
- 当机器断电或网线断开时,TCP连接会突然中断。
- 如果断电的是接收方,发送方在发送数据时无法收到ack确认应答,会触发超时重传机制。重传多次后仍未收到应答,会重置连接并发送RST报文。如果仍得不到应答,则会断开连接。
- 如果断电的是发送方,接收方会尝试接收数据但失败,此时接收方可能会采取心跳包机制来检测发送方的状态。
(4)网络故障
- 网络不稳定、中间交换机故障等网络问题可能导致TCP连接异常。
- 这些问题可能导致数据包丢失、延迟或乱序,从而影响TCP连接的稳定性和可靠性。
(5)应用程序错误
- 应用程序中的网络编程部分可能存在错误,如未正确处理异常情况、资源泄漏等。
- 这些错误可能导致TCP连接异常关闭或无法建立连接。
3、TCP保活机制
- TCP保活机制(keepalive)可以在双方没有数据交互的情况下,通过探测报文来确定对方的TCP连接是否存活。如果一方崩溃或无法响应探测报文,另一方可以及时发现并断开连接。
4、心跳包
- 心跳包是一种自定义的探测报文,用于检测连接双方的状态。
- 发送方定期发送心跳包给接收方,接收方收到后回复确认报文。如果发送方在一定时间内未收到确认报文,则认为连接已断开或异常。
后续内容参见TCP协议(二)
本文到这里就结束了,如有错误或者不清楚的地方欢迎评论或者私信
创作不易,如果觉得博主写得不错,请点赞、收藏加关注支持一下💕💕💕
更多推荐
已为社区贡献1条内容
所有评论(0)