**面试题三:像王者荣耀,吃鸡使用的是什么协议? **
都不一定,既要保证TCP的一些特性,又要保证效率,其实都不一定,有的协议可能会更好的兼顾可靠性和效率,付出的代价可能是浪费更多的机器资源;知乎上的一位大神,自己开发了KCP协议,效率变得更高了,这样就更适用于即时性更高的游戏;
传输的效率,不仅仅取决与接收方,还和传输路径以及中间链路连接有关
** 6 拥塞控制**
虽然TCP有了滑动窗口这个大杀器,可以相当可靠的发送大量的数据,但是如果在刚开始的阶段就发送大量的数据可能会引发问题,网络上有很多的计算机,可能当时的网络状态很拥堵,若不i清楚网络状态,贸然发送大量的数据,很可能会导致网络系统瘫痪
本质上是在另一个角度上来控制发送方的窗口大小,他是站在一个宏观角度来看待问题,他是把中间的链路都看成了一个整体,只看结果,是一个不断尝试的过程;
先用一个较小的窗口来传输数据,看看是否丢包;如果不丢包,说明网络通畅;如果丢包,说明网络拥堵;当我网络通畅的时候,就加大传输速率;如果当前网络不丢包的情况下,就立即降低发送速率;通过这样的方式,就可以直接试出来当前最合适的窗口大小;
流量控制针对的是接收方一个元素针对的,拥塞控制针对的是整体进行限制,会动态变化的;
**真实的窗口大小取流量控制的窗口和拥塞控制的窗口他们的较小值; **
**刚开始启动的时候,窗口比较小,此时通过指数增长,就可以在很少的轮次上把窗口大小给顶上去。如果达到阈值,就会从原来的指数增长变成线性增长。 **
** 7 延时应答:让窗口大小保证在可靠的基础上,效率再高一些,窗口争取再大一些,在A发数据的时候,本应会返回一个ACK,但是这时缓冲区的大小可能会发生变化(可能会减少很多,这时B就对数据的需求量更大了),所以我们可以让ACK等一会再发出去;(在B向A发ACK的时候,B可能会消费的更多,缓冲区的剩余就更多,这时下次A再发的数据就可能会让缓冲区填不满)**
举一个生活中的例子:我去给老板送货,现在老板的送货架上可以放100份方便面,现在架子上有70份,过了一小时后,卖了50份;我这时问老板,要进货吗?老板说一会再告诉你,又过了一小时,货全部卖完了,这是我就可以送100份方便面了。如果老板一小时之前就告诉我,我送的货就是80份。这样一来,就提高了我们的效率; 8 捎带应答 内核中只要收到数据就会立即返回ACK,这是应用程序进行的响应
但是有了延时应答,返回的ACK不会立即返回,而是要等一会,正好在这里等一会的过程中,服务器要返回请求了,正好可以把这个ACK和response合成一个包;因为在网络过程中,对于数据涉及到大量的封装和分用,收到之后还要进行解析;
**之前我们说过,四次挥手是有可能变成三次挥手的,但是具体的概率是不知道的 **
捎带应答是建立在延时应答的基础上的 ,他是有可能把中间的ACK和FIN合并到一起的
**例如在服务器收到请求并返回响应,这个过程中消耗50ms,但是演示应答最多等待20ms,这个时候就无法触发捎带应答了, 所以说它本质上是一个概率上的机制;但是此时假设演示应答最多是等60ms,第50ms的时候,此时出发了响应,这个时候ACK就可以和FIN一起过去了,也就出发了延时应答; **
这是延时应答的一种情况 9面向字节流(可能会出现粘包问题)
应用程序从接收缓冲区中读数据的时候,就不知道从哪里到哪里是一个完整的应用层数据包了;应用程序此时只能看到接收缓冲区中的一个一个的字节;无法区分当前应用层有多少个应用层数据包,以及从哪里到哪里是一个完整的应用层数据报;
那么如何解决这个粘包问题呢?应该通过再设定一个合理应用层协议
1给应用层数据设置结束符,分隔符
2 设定数据包的长度
但是在UDP协议中,就不会涉及到这样的问题;
10 TCP中的一些异常问题
1 进程终止:不管进程中是怎么终止的,本质上都会对应释放PCB,也会释放对应的文件描述符,一样会触发四次挥手,进程终止并不意味着连接就终止,进程终止本质上是调用了socket.close()而已
2 机器重启:机器重启的时候,其实也是在先杀进程,仍然是先触发四次挥手;
3 机器掉电/网线断开 这是属于一种突发情况,机器来不及进行任何动作的
1)掉电的是接收方,此时另外一边还会继续传输数据,显然发送方不会再收到ACK,于是就会进行超时重传操作,重传几次之后,就会进行重置连接;
**但是此时连接还是连不上,这时发送方就会将连接对应的资源回收掉; **
2)掉电的是发送方:此时另外一方正在尝试接收数据,但此时不会收到任何数据,此时的接收方如何知道发送方是挂了呢,还是说发送方暂时没有发呢?这是接收方采取的策略,就会发送一个PING包,此时他也期待对方可以给它返回一个PING包,如果反复发送几次后对方也不应答,就会认为发送方已经挂了
TCP报头结构
1 32位确认序号: 用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1。假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同时携带自己的序号和对A发送来的报文段的确认号。
2 32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号
3 4位首部长度:标识该TCP头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
**4 16位窗口大小(流量窗口):**是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
5 16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
6 16位紧急指针:TCP的紧急指针是发送端向接收端发送紧急数据的方法。
7 选项:TCP头部的最后一个选项字段(options)是可变长的可选信息。
8 6位保留:
** URG标志,表示紧急指针(urgent pointer)是否有效。**
** ACK标志,表示确认号是否有效。我们称携带ACK标识的TCP报文段为确认报文段。**
** PSH标志,提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间(如果应用程序不将接收**
** 到的数据读走,它们就会一直停留在TCP接收缓冲区中)。**
** RST标志,表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。**
** SYN标志,表示请求建立一个连接。我们称携带SYN标志的TCP报文段为同步报文段。**
** FIN标志,表示通知对方本端要关闭连接了。我们称携带FIN标志的TCP报文段为结束报文段。**
版权归原作者 学不会二叉树的小比特 所有, 如有侵权,请联系我们删除。