TCP详解——各标志位
目录
标志位
拥塞控制
标志位
TCP有六位标志位,分别代表不同的含义
URG:表示紧急指针是否有效,URG的存在是为了让某些数据可以被接收方优先处理,这种数据被称为带外数据(Out-Of-Band Data),而与之相对的就是普通的带内数据
带外数据不遵循普通数据的队列顺序,也不受滑动窗口的限制,不像普通数据必须得等待接收到连续的一段数据,带外数据可以插队
URG为1时,紧急指针就指向了紧急数据,紧急数据很多时候都只有一个字节,用来传递某些信息
比如在下载任务中,如果下载到一半向取消,发送的报文就会带有URG标志位,会让服务器优先处理取消请求
Linux中要读取紧急数据,可使用recv接口
#include <sys/types.h>
#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
将其中的flags标志位设为MSG_OOB,就会读取紧急数据
ACK:确认号是否有效,指的是下一次应该收到的序列号
PSH:提⽰接收端应⽤程序⽴刻从TCP缓冲区把数据读⾛
TCP 协议中,发送方和接收方通常会使用缓冲区临时存储数据(例如发送方积累一定量数据后再打包发送,接收方缓冲数据后批量提交给应用),以减少网络交互次数、提高传输效率。但在某些场景下(如实时通信、交互式操作),需要数据 “即时处理”,此时 PSH 标志位就会发挥作用:
发送方设置PSH=1,告诉接收方 “本报文中的数据是紧急需要处理的,不需要等待后续数据填充缓冲区,请立即交给应用层”。
接收方收到PSH=1的报文,会立即将当前接收缓冲区中所有已接收的数据(包括本报文的数据)传递给应用程序,而不是等待缓冲区满或超时。
RST:对⽅要求重新建⽴连接; 我们把携带RST标识的称为复位报⽂段
有时服务器会崩溃,操作系统就会向已经建立连接的客户端发送RST包,客户端就能知道连接已经断开,就可以采取应对措施;或者有时三次握手客户端发出的最后一个SYN包没有被服务器接收到,而客户端认为连接已经建立,开始发送数据,服务端却并没有建立连接完成,这时服务器会向客户端发送RST包
SYN: 请求建⽴连接; 我们把携带SYN标识的称为同步报⽂段
FIN: 通知对⽅, 本端要关闭了, 我们称携带FIN标识的为结束报⽂段
拥塞控制
发送数据并不能一开始就发送大量的数据,很可能网络正处于严重的堵塞,此时无异于雪上加霜,为此,TCP引入了慢启动机制,先发送少量数据探明网络整体拥堵情况,再根据具体拥塞情况来调整发送速率
此时也可以意识到,之前对于滑动窗口大小的讨论还不够全面,只考虑了对端的接收情况而没有考虑网络情况
此处引⼊⼀个概念称为拥塞窗⼝,可以认为在一定程度上,发送的数据段数量高于这个值就会引发网络拥塞,拥塞窗口是一个整型变量
发送开始的时候, 定义拥塞窗⼝⼤⼩为1
每次收到⼀个ACK应答, 拥塞窗⼝加1
每次发送数据包的时候, 将拥塞窗⼝和接收端主机反馈的窗⼝⼤⼩做⽐较, 取较⼩的值作为实际发
送的窗⼝,所以拥塞窗口会控制发送窗口的大小,初始是1,只发送一个数据段,收到应答后变为2,这里假设接收端的接收能力强,一直大于拥塞窗口大小,接着会发送两个数据段,在一个RTT(往返时间)内,会收到两个ACK应答,那么拥塞窗口加2,变为了4
从上面可以看出,拥塞窗口会按照指数级别增长,也就是通过这个指数增长,实现了慢启动
而拥塞窗口并不能无限制增大,此处引入慢增长的阈值,拥塞窗口超过这个阈值,就会不再按照指数增长,而是改成线性增长
这个阈值实现方案不同系统可能不同,但初始都是一个比较大的值
上图阈值初始是16,到达16后就是线性增长,然后在拥塞窗口大小为24时,网络拥塞导致了超时重传,将阈值减小,这就导致了超时重传后发送的速度进一步变慢了
所以,一直维护拥塞窗口的大小(尤其是增大)是有意义的,尽管它变大到一定值不再对发送窗口的大小产生影响,但是持续增大他,可以使下次超时重传的阈值更大,使发送速度更加贴合网络的情况
关于阈值具体该怎么变化,可能有不同的算法实现,但是基本思想是一致的