初步认识TCP协议——TCP的紧急状态

当URG位为1时,TCP头部节点的紧急指针位会记录一个偏移量,指向紧急数据的最后一位(也可以是紧急数据的下一位,两者都是标准),在读取到紧急指针所指向的位置之前,TCP的接受进程都处于紧急状态,当读取到紧急数据后一位时,回复到正常状态。

从上面的特性可以看到,TCP无法告诉紧急数据从哪里开始,只能告诉紧急数据从哪里结束,URG位为1的TCP报文并不是带外数据。抄袭一段百度上的解释:

传输层协议使用带外数据(out-of-band,OOB)来发送一些重要的数据,如果通信一方有重要的数据需要通知对方时,协议能够将这些数据快速地发送到对方。为了发送这些数据,协议一般不使用与普通数据相同的通道,而是使用另外的通道。但是TCP协议没有真正意义上的带外数据。为了发送重要协议,TCP提供了一种称为紧急模式(urgent mode)的机制。TCP协议在数据段中设置URG位,表示进入紧急模式。接收方可以对紧急模式采取特殊的处理。



先来说说为什么TCP协议不会有带外数据吧,以下是我的理解,原因很简单,从发送主机到接收主机方向的通道只有一条,若要发送带外数据,不是还要建立另外一个TCP连接?TCP连接占用的资源比较大,且连接的建立与释放会耗费一定的时间,每次连接不一定都会频繁的发送紧急数据,甚至不会发送,此时占用资源的利用率非常低,所以TCP协议不会有带外数据

那么TCP协议栈进入到紧急模式后做些什么呢?

发送端也可以进入紧急模式,TCP协议栈会为每个套接字维护一个发送端紧急模式标志和一个发送端紧急指针,当发送端TCP协议栈得知有紧急数据要发送时(即某个进程调用了sendMSG_OOB)函数),将发送端紧急模式置为1,同时将紧急指针的值记录在发送端紧急指针处,随后进入紧急状态,含有未发送字节到紧急字节之间数据的报文都会将URG位置为1,设置紧急指针的值,进入紧急模式后,无论数据字节是否发出,URG紧急通知都会发送(数据流会因为TCP流量控制而停止,紧急通知总是无障碍的发送到对端TCP),但紧急数据因为滑动窗口满而不随同发送
当含有紧急字节的报文发送并确认接收后,发送端会解除紧急状态。

如下图:


关于紧急通知的发送不受流量控制的影响可以看下图,图片来源于《TCP\IP协议详解卷一:协议》


可以看到,第十一个字段返回时指出了窗口大小为0,但sun还是发送了含紧急通知的报文(第十二个字段)。接着第十四个字段中真正包含紧急数据。


接收端TCP协议栈也会给每个套接字配上紧急模式标志和紧急指针接收端在接收到TCP报文后,若发现TCP头部的URG位为1,则将紧急模式标志置为1,保存紧急指针的值,随后进入接收端紧急模式,通知接收进程,此后,TCP监听每一个收到的数据字段,若其中含有紧急字节,则将该字节放在单独的带外缓冲区中(独立于接收缓冲区),如果接收端对套接字调用setsockopt开启了SO_OOBINLINE,此字节将混在普通数据中,称为在线接收。在接收进程读取数据时,只有在下一个待读字节越过紧急字节之后,接收端紧急模式才被解除。

下面谈谈我的一些理解,如果有错误,希望指出

从上面的TCP紧急模式的机制可以看到,似乎没有加快将数据交给应用程序处理的步骤,TCP做的只是尽快将紧急数据发送出去,尽快将紧急数据从内核缓冲区放到接收缓冲区中,也许在设计应用程序时,就要考虑到TCP协议栈进入到紧急状态时,本应用程序该做什么吧(例如加快数据处理速度等)。




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值