TCP协议原理三
创始人
2024-06-03 06:22:53
0

在这里插入图片描述

文章目录

  • 七、延时应答
  • 八、捎带应答
  • 九、面向字节流
    • 粘包问题
  • 十、TCP异常情况
  • 总结

七、延时应答

如果说滑动窗口的关键是让窗口大一些,传输速度就快一些。那么延时应答就是在接收方能够处理的前提下,尽可能把ack返回的窗口大小尽可能大一些。
如果在接受数据后立即返回ack应答报文,这时候返回的窗口大小比较小。

假设我们接收端的缓冲区大小为64kb,收到了32kb的数据,如果立即应答,返回的窗口大小就是32kb.
但实际上我们接收端处理数据的速度很快,10ms内就将这32kb的数据处理掉了,这种情况下,接收端处理还没有达到自己的极限,这时我们将窗口放大一些,也是可以处理过来的。
如果我们接收端稍等一会在应答,比如等待200ms后,这时候返回的ack窗口大小就是64kb。

所有的包都可以延时应答吗?
不是。

  1. 数量限制:每隔N个包就应答一次
  2. 时间限制:超过最大延迟时间就应答一次
    这里的数量和时间不同操作系统有差异,一般超时时间取200ms,N取2
    在这里插入图片描述
    我们可以发现延时应答的方式下,在滑动窗口下并不是每条ack都返回,这里是隔1条发一条。在这等待的时间里,接收方的程序就能把缓冲区的数据处理一波,ack返回的窗口大小就更大了。

八、捎带应答

大多数情况,客户端服务器是"一收一发"的,比如客户端给服务器说了“what’s your name?" ,服务器回回一个"fine, zd"。在我们延时应答的基础上,我们ack就可以一次性将"fine, zd"发给客户端。
在这里插入图片描述
这两个响应是处于不同时机的,但是我们TCP存在延时应答,我们就可以让业务数据响应和ack一起发给客户端A
在这里插入图片描述
大家需要注意这里和TCP三次握手的区别,TCP三次握手本身就是相同时机,所以一定会合并的。而我们这里是处于不同时机的,只是在延时应答机制下,可能会成为同一时机,所以是有机会合并的。

九、面向字节流

我们在创建一个TCP的时候会在内核中创建一个发送缓冲区接收缓冲区

我们在调用write时首先数据回写入到发送缓冲区中,如果发送字节数的太短就先在缓冲区里等待,等到缓冲区长度差不多了,或者其他时机发出来。如果发送的字节数太长就会拆分多个TCP数据包发出去。
接受数据的时候,从网卡驱动程序拿到内核的接收缓冲区,然后程序调用read去缓冲区拿数据。
我们TCP的连接也是有发送,接收缓冲区的,对于这一连接既可以读数据,也可以写数据,这也就是全双工

正是因为上述缓冲区的存在,我们TCP的读和写不需要一一匹配。
在这里插入图片描述
我们在读15字节数据时,不需要考虑数据时怎么写的,可以一次read15个字节,也可以一次read一个字节,读15次,这就导致我们一次性读到的数据,可能是半个应用层数据报,也可能是一个应用层数据报,也可能是多个应用层数据报
正是因为上述情况,会出现一个经典问题:粘包问题

粘包问题

首先大家需要明确,我们这里的包指的是应用层的数据包,因为站在应用层的角度,看到的只是一连串的字节数据,不知道从那部分到哪部分是一个完整的应用层数据包。
在这里插入图片描述
我们应用程序在调用read
如果read 3个字节,此时刚好读到 a b c,读到了一个完整的数据报
如果read 4个字节,此时读到a b c d,读到了一个半数据报
如果read 2个字节,此时读到a b,读到了半个数据报
在我们TCP层次,并没有socket api去告诉我们该读多少字节,完全靠我们程序员字节去负责。
那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界
1.约定好分隔符

//伪代码
while(true) {byte c = s.read();if(c == '分隔符') {bread;}
}   

我们之间在写网络通信的时候,使用println写数据就是为了加上这个分隔符。
2.约定好包的长度

byte[] lenBuffer = new byte[4096];
s.read(lenBuffer);
int len = parseInt(b);
byte[] dataBuffer = new bytep[len];
s.read(dataBuffer);

UDP协议,是否会出现粘包问题?
对于UDP来言,如果没有交付给应用层,那么UDP报文长度依然存在,UDP是一个一个将数据交付给应用层,有明确的数据边界,应用层要么收到完整的UDP报文,要么不收。

十、TCP异常情况

这里我们TCP异常分为两大类型
第一类:
进程挂掉了,主机关机了(我们手动关机).
这一类TCP异常,进程挂了,对应的PCB也就没了,对应文件描述符表也就释放了,相当于调用了socket.close(),然后内核会继续完成四次挥手。主机关机也是会杀掉进程然后才关机,和上述进程挂了是相同的过程,此时这些都是属于一个正常断开的流程。

第二类:
主机断电,网线掉网
大家需要注意这种情况,是无法进行四次挥手的。
如果是接收方出现异常,发送方在ack的时候,一直等不到,超时重传之后也收不到ack,如果重传几次后都没有应答,就会重置TCP连接,如果重置后仍然还不能收到ack,那么发送方就单方面放弃了。
如果是发送方出现异常,我们接收方发现没数据了,对方是正在发还是挂掉了,不管什么原因先等一会,但接收方需周期性的给发送方发送一个消息(心跳包 保活机制),确认对方是否在正常工作。

总结

我们TCP是十分负责的,因为不仅要保证可靠性,而且也要尽可能的提高性能
可靠性:

校验和
序列号(按序到达)
确认应答
超时重传
连接管理
流量控制
拥塞控制

提高性能:

滑动窗口
快速重传
延迟应答
捎带应答

相关内容

热门资讯

殢人娇,殢人娇李流谦,殢人娇... 殢人娇,殢人娇李流谦,殢人娇的意思,殢人娇赏析 -诗词大全  殢人娇,殢人娇李流谦,殢人娇的意思,殢...
乞巧节的古诗句 乞巧节的古诗句  乞巧节,即七夕节,这个节日起源于汉代,一起来看看古诗句,仅供大家参考!谢谢!  1...
七字古代唯美诗句爱情 七字古代唯美诗句爱情  未曾青梅,青梅枯萎,芬芳满地 不见竹马,竹马老去,相思万里 从此,我爱上的人...
不知天上宫阙 “不知天上宫阙”出处 出自 宋代 苏轼 的《水调歌头》“不知天上宫阙”平仄韵脚 拼音:bù zhī ...
“海阔凭鱼跃,天高任鸟飞”的... “海阔凭鱼跃,天高任鸟飞”的意思及出处 宋·阮阅《诗话总龟前集》卷三十引《古今诗话》谓:唐代大历年间...
描写秦淮河的古诗句 描写秦淮河的古诗句  烟笼寒水月笼纱,夜泊秦淮近酒家。商女不知亡国恨,隔江犹唱后庭花。  陵古形胜,...
描写梅花精神的诗句   1、已见寒梅发,复闻啼鸟声。心心视春草,畏向玉阶生。  2、君自故乡来,应知故乡事。来日倚窗前,...
空山新雨后天气晚来秋诗句赏析 空山新雨后天气晚来秋诗句赏析  在平平淡淡的学习、工作、生活中,大家都经常接触到诗句吧,诗句是组成诗...
贺铸古诗鉴赏 贺铸古诗鉴赏  贺铸  急雨收春,斜风约水,浮江涨绿鱼文起。  年年游子惜余春,春归不解招游子。  ...
赞美桃花的优美诗句 赞美桃花的优美诗句(精选110句)  在日常学习、工作抑或是生活中,大家或多或少都接触过一些经典的诗...
《月夜忆舍弟》古诗鉴赏 《月夜忆舍弟》古诗鉴赏  《月夜忆舍弟》原文  戍(shù)鼓断人行,边秋一雁声。  露从今夜白,月...
郭沫若的诗歌 郭沫若的诗歌(通用9篇)  在平时的学习、工作或生活中,许多人都接触过一些比较经典的诗歌吧,诗歌具有...
唐代诗人李白简介及代表作 唐代诗人李白简介及代表作  李白有《李太白集》传世,诗作中多以醉时写的,代表作有《望庐山瀑布》《行路...
《哀江头》杜甫唐诗鉴赏 《哀江头》杜甫唐诗鉴赏  哀江头  杜甫  少陵野老吞声哭,  春日潜行曲江曲。  江头宫殿锁千门,...
描写和赞美塔尔寺的诗句 描写和赞美塔尔寺的诗句  (第一首)  湟水流经山坳中,如来八塔映天空。  衣冠络绎观三绝,袍袖匍匐...
老舍的经典名言名句 关于老舍的经典名言名句  1、的智慧,加上孩子的天真,或者就能成个好作家了。  2、美丽的人是不多施...
“楼上阑干横斗柄,露寒人远鸡... 楼上阑干横斗柄,露寒人远鸡相应。 [译文] 北斗星已斜挂在高楼之上,清晨露寒,离人走远,只有晨起的鸡...
描写桥的诗句 描写桥的诗句(精选90句)  在平时的.学习、工作或生活中,大家都经常接触到诗句吧,诗句通常按照诗文...
庆祝元宵节古诗鉴赏 按中国民间的传统,在一元复始,大地回春的节日夜晚,天上明月高悬,地上彩灯万盏人们观灯、猜灯谜、吃元宵...