JavaEE初阶---网络原理值TCP篇(三)
文章目录
- 1.延时应答机制
- 2.捎带应答
- 3.面向字节流---粘包问题
- 3.1问题引入
- 3.2解决方法
- 4.异常情况的处理
- 5.TCP的心跳机制
- 6.TCP/UDP的对比
1.延时应答机制
例如我们的这个剩余空间大小10kb,如果我们直接返回ack,这个发送方的窗口大小只能是10kb,但是如果我们进行延时,例如我们演示200ms,这个时间里面,我们的这个接收方就处理2kb,这个时候我们的返回的ack就是12kb,这个时候我们的发送方的窗口大小就可以调大一些,提高传输效率;
2.捎带应答
这个是在我们的延时应答的基础上面的;我们的这个延时应答就会导致这个ack返回的这个时间不是一触即发的,而是需要等待一部分时间,当我们的这个等待时间到了这个socket执行这个close操作的时候,我们的这个ack和fin就会被一起返回去,这个就是顺路的事情,因此我们把这个情况称之为捎带应答;
3.面向字节流—粘包问题
3.1问题引入
当我们的这个应用层的数据包被按照下面的这个方式进行传输的时候:
在我们的这个接受方的缓冲区,实际上就是连接在一起的,这个时候我们的接收方根本就不知道这个数据是一次方送过来的还是多次发送过来的,至于我们是三次发送过去的这个情况,我们的这个接收方根本就不知道;
3.2解决方法
1)引入分隔符:
例如下面的这个就是引入我们的这个\n作为分隔符,这个时候我们的这个接收方从这个缓冲区进行这个数据的读取的时候,就知道这个是几个部分;
2)引入长度:
我们的这个发送方进行这个aaa发送的时候,标记上这个数据的长度3,其他的发送的数据包也是以此类推,这样的话我们的这个接收方从这个数据缓冲区里面读取数据的时候,就知道根据这个标识的长度知道一次性读取的这个数据的长度----有效的解决我们的粘包问题;
4.异常情况的处理
进程崩溃:这个时候进程结束了,就会触发我们的这个fin,直接进行这个正常的4次挥手的过程;
主机关机:这个时候先会触发这个终止进程,此时就会发送这个fin,对方收到之后就会返回这个fin和ack,实际上就是我们的四次挥手,但是这个时候我们的继承已经终止了,这个系统可能已经关闭了,如果这个时候的系统已经关闭了,我们的这个ack和fin来迟了,这个时候我们的最后的一个(也就是4次挥手里面的第四次)ack也就无法响应,我们的这个接收方就会认为是自己的这个相应对方没有收到,这个时候就会不断的进行重传,但是这个时候我们的对端已经挂掉了,因此他在重新传输几次之后就知道不是自己的问题,这个时候对端也会断开连接(这个过程的理解需要不断的结合我们上面介绍的这个四次挥手的过程);
掉电关机:这个就是一瞬间的情况,我们的彼此根本就不知道是什么情况,下面分为两个情况进行考量:
1)我们的接收方掉电:我们的发送方等待返回的这个ack,但是因为我们的接收方已经因为这个掉电挂掉了,因此这个时候就会触发超时重传,触发我们的这个TCP里面的重置链接,发起“复位报文段”;
2)我们进行数据发送的这一方掉电:这个时候我们的这个接收方还在等待我们发送的数据,这个时候我们的接收方没有办法确认这个是数据没有发送还是我们的这个发送方已经挂掉了;
在我们的这个TCP里面,提供了这个心跳包的机制:就是不携带任何的业务逻辑,希望得到对方的一个应答,如果对方没有进行应答,而且我们重复多次之后都是没有相应的,我们的这个接收方就视为这个发送方挂掉了,这个时候就会释放连接;
网线断开:这个情况下实际上和这个掉电的情况基本一致:
A----------------------------B之间通信:
我们的这个时候两个之间正在进行通信,这个时候网线断开:
A就会不断的进行超时重传–》连接重置----》单方向的是释放这个链接;
B会触发这个心跳包----》发送端没有进行任何的响应—》单方面的释放连接;
5.TCP的心跳机制
我们进行日常的开发的时候,经常会遇到这个心跳机制(尤其是在这个分布式系统上面)
如何识别这个机器是不是挂掉了,这个时候就可以使用我们的心跳进行检测,一般我们后面用到的这个心跳,都是在这个应用程序里面自主实现,而不是像这个TCP里面的这个心跳;
两个的区别就是:
自主实现的心跳很敏感,时间很短,但是我们自己里面的这个TCP的心跳机制周期很长;
6.TCP/UDP的对比
1)TCP的优势是可靠传输,适用于绝大多数的场景;
2)UDP的优势是进行高效率的传输,适合于可靠性不敏感,性能要求高的场景------局域网内部之间进行的通信,因为一个局域网里面自己进行通信的时候,出现丢包的情况不大,我们这个时候希望的是高效的传输数据;
3)如果是传输比较大的数据包,TCP优先,因为我们的这个UDP有64位传输大小限制;
4)广播传输:优先使用UDP,UDP天然支持广播传输,如果使用TCP的话,需要我们自己写代码;
==什么是广播?==就是我们的数据需要发送给这个局域网里面的所有的设备,这个就是广播;
例如我们生活里面的这个投屏:我们的手机向局域网里面的所有设备都发送这个数据包,询问:你们谁是电视,谁可以接受我的投屏,电视这个时候会进行回应,并且把自己的这个端口号和IP告诉了手机,手机就可以实现投屏,在这个过程里面,我们的这个手机寻找投屏设备的时候:把数据包发送给这个局域网里面的所有的设备,这个就是广播的过程;