文章目录
- TCP协议概括
- TCP头部格式
- TCP连接管理
- 建立连接(三次握手)
- 数据传输
- 确认应答机制
- 捎带应答
- 滑动窗口
- 丢包问题
- 拥塞控制
- 延时应达
- 终止连接(四次挥手)
TCP协议概括
TCP是一个面向连接的协议,在传输数据之前需要建立连接,确保通信双方的准备工作。它提供可靠的数据传输服务,通过确认、重传、流量控制和拥塞控制机制,保证数据准确且按顺序地到达目的地。
TCP头部格式
源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去。
32位序号: 数据段的序列号,用于重组数据流和检测丢失数据
32位确认号:确认收到的数据段的序列号(当收到确认序列号时,可以保证的是,此序列号之前的序列号都已经处理完成,即使没有收到对应的序列号)。
如下图:(1-100)是客户端发给服务器的数据段序号,101则是服务端对客户端发送过来数据的确认(确认应答机制)。
4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 (1111)* 4 = 60(注意乘4)
6位标志位:
URG: 紧急指针是否有效
ACK: 确认号是否有效
PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
在每次发送报文以及应答报文时,对于以上六中的请求,会分别对对应请求的标志位的值标志位1,来表示此数据的意义!
16位窗口大小:流量控制窗口大小,接收方可以接受的最大数据量。(每次进行报文通信时,都会将自己的接受缓冲区的具体大小告诉对方,好让对方发送我们所能接受的字节流,以防于数据过大,导致丢包问题!)
16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分
16位紧急指针: 标识哪部分数据是紧急数据(配合标志位的URG使用)。
选项:可选字段,用于扩展TCP协议的功能
数据:实际传输的数据。
TCP连接管理
TCP是面向连接的协议,通信双方在传输数据之前必须先建立连接。连接管理包括连接建立、数据传输和连接终止三个阶段。
建立连接(三次握手)
TCP使用三次握手机制建立连接,确保双方同步并准备好数据传输。
SYN:客户端发送一个SYN(同步)报文段,表示请求建立连接,同时发送初始序列号。
SYN+ACK:服务器接收到SYN报文段后,发送一个SYN-ACK报文段,确认收到SYN,并发送自己的初始序列号。
ACK:客户端接收到SYN-ACK报文段后,发送一个ACK(确认)报文段,确认收到服务器的SYN。
通过三次握手,客户端和服务器确认彼此的存在,并交换初始序列号,准备传输数据。
为什么要进行三次握手?
解决SYN洪流问题!因为如果是一次或者两次握手,一些恶意的客户端,对服务器进行多次连接攻击,只要服务端收到来自客户端的连接,不论是一次还是两次,都会直接建立连接快速消耗内存,导致服务器挂掉,而三次握手需要客户端的再次确认返回,才会进行建立连接,虽然也会有SYN洪流问题,但要比之前的方式减少些许负担,同时还可以最小成本的验证全双工,客户端可以验证发送以及接受正常通信,服务端也可以验证发送以及接受的正常通信。
数据传输
确认应答机制
每收到一个数据段,接收方都会发送一个确认报文段(ACK),确认收到的数据段序列号。发送方如果在一定时间内没有收到确认,则会重传该数据段。
如上图是一种串行发送消息,效率可见是非常慢。所以有下图的多行发送消息,特别注意这里每次发送数据都是报头携带数据的。而返回的应答ACK则只有报头,在报头内将ACK标志位置为1
而这样收到的报文可能是乱序的这样就可以靠TCP报头的序列号进行排序,处理。
捎带应答
对于上面的ACK应答报文,也可以被携带在返回数据中,例如你向服务器发问1+1等于多少?服务器会给你回应2同时报头中ACK的标志位置为1,表示对你1+1的信息收到了。这样就可以将两个通信合并为一条。大大提高效率。
滑动窗口
针对确认应答机制中的多行并发消息的解决。滑动窗口的初始大小是根据接收方返回报头数据中自己的的接受缓冲区的大小来决定的,同时也达到流量控制的目的(当然对于网络中进行通信有多个路由器等硬件设施,具体的滑动窗口的大小会根据这些硬件设施所能接受的大小与对方接受缓冲区的大小取最小值来设定!!)
TCP使用滑动窗口机制进行流量控制,接收方根据自己的接收能力设置窗口大小,告诉发送方可以发送的最大数据量
如下图一次性发送一个窗口内所有的内容。倘若接受到2001的确认信号,那么窗口的左坐标就会移动到2001的位置,右坐标也会相应的增加到6001
把窗口的前坐标比作win_start,结尾坐标比作win_end,具体滑动就是根据下面的公式进行更变。
丢包问题
因为有应答序号,保证次序号之前的消息都已经收到,所以1001——2000丢包,后面数据即使收到,也只会返回1001这个确认序号,经过多次重复应答,主机A就知道,1001——2001丢了,对方没有收到,则会再次发送此数据。
这种机制被称为 “高速重发控制”(也叫 “快重传”)
拥塞控制
控制滑动窗口大小的另一个决定因素
TCP通过慢启动、拥塞避免、快重传和快恢复等算法进行拥塞控制,防止网络过载。
慢启动:在连接初始阶段,发送方以指数增长方式增加发送窗口大小,快速探测网络容量。
拥塞避免:当慢启动阈值达到一定值时,发送方以线性增长方式增加发送窗口大小,避免网络拥塞。
快重传和快恢复:当发送方收到重复确认(ACK)时,快速重传丢失的数据段,并进行快速恢复,减少网络等待时间。
发送开始的时候, 定义拥塞窗口大小为1;
每次收到一个ACK应答, 拥塞窗口加1;
每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口;
像上面这样的拥塞窗口增长速度, 是指数级别的. “慢启动” 只是指初使时慢, 但是增长速度非常快.
为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍.
此处引入一个叫做慢启动的阈值
当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长
少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;
拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案
延时应达
当收到多个数据请求时,接收方的接收缓冲区就会变小,此时如果对多个数据请求先来的做出应答,那么对于应答携带的报头中发送给对方的可接受缓冲区的大小是非常小,会降低下一次发送的效率,所以我们引入延时应达,我们可以等一次性收到的全部数据都处理完,通过序列号的排序,仅仅应答最后一个序列号即可(因为确认序列号可以保证携带之前序列号的数据已经收到并处理)
具体的延时应答策略:
数量限制: 每隔N个包就应答一次;
时间限制: 超过最大延迟时间就应答一次
具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间取200ms
终止连接(四次挥手)
TCP使用四次挥手机制终止连接,确保双方都能够正常结束数据传输。
FIN:一方(通常是客户端)发送一个FIN(终止)报文段,表示不再发送数据,但仍然可以接收数据。
ACK:另一方(服务器)接收到FIN报文段后,发送一个ACK报文段,确认收到FIN。
FIN:服务器发送自己的FIN报文段,表示不再发送数据。
ACK:客户端接收到FIN报文段后,发送一个ACK报文段,确认收到服务器的FIN。