网站公司做网站,东莞临时工最新招聘,网络推广专员主要的工作内容,7k7k小游戏网页版文章目录七、延时应答八、捎带应答九、面向字节流粘包问题十、TCP异常情况总结七、延时应答
如果说滑动窗口的关键是让窗口大一些#xff0c;传输速度就快一些。那么延时应答就是在接收方能够处理的前提下#xff0c;尽可能把ack返回的窗口大小尽可能大一些。 如果在接受数据… 文章目录七、延时应答八、捎带应答九、面向字节流粘包问题十、TCP异常情况总结七、延时应答
如果说滑动窗口的关键是让窗口大一些传输速度就快一些。那么延时应答就是在接收方能够处理的前提下尽可能把ack返回的窗口大小尽可能大一些。 如果在接受数据后立即返回ack应答报文这时候返回的窗口大小比较小。 假设我们接收端的缓冲区大小为64kb收到了32kb的数据如果立即应答返回的窗口大小就是32kb. 但实际上我们接收端处理数据的速度很快10ms内就将这32kb的数据处理掉了这种情况下接收端处理还没有达到自己的极限这时我们将窗口放大一些也是可以处理过来的。 如果我们接收端稍等一会在应答比如等待200ms后这时候返回的ack窗口大小就是64kb。 所有的包都可以延时应答吗? 不是。
数量限制每隔N个包就应答一次时间限制超过最大延迟时间就应答一次 这里的数量和时间不同操作系统有差异一般超时时间取200msN取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是十分负责的因为不仅要保证可靠性而且也要尽可能的提高性能 可靠性 校验和 序列号(按序到达) 确认应答 超时重传 连接管理 流量控制 拥塞控制 提高性能 滑动窗口 快速重传 延迟应答 捎带应答