【网络相关面试问题——八股文篇(中)】

目录

一、传输层中关于TCP的其余内容

1、关于连接管理中如何断开连接?

三次握手和四次挥手的区别:

不能合并的原因:

 关于断开连接,我们需要了解两个比较重要的状态:

2.滑动窗口

此时我们忽略了一个很重要的问题:丢包~!!!!

三、流量控制

 四、拥塞控制

五、延时应答

六、捎带应答(延时应答的延伸)

 七、面向字节流=》粘包问题

八、TCP异常处理

(1)进程终止

(2)机器关机

(3)机器掉电、网线断开

总结:


在上篇中我们说到了关于保证TCP可靠传输的连接管理机制,需要重点理解三次握手的含义~

接下来我们来继续探究关于网络的其他知识~

一、传输层中关于TCP的其余内容

1、关于连接管理中如何断开连接?

在三次握手成功之后,客户端和服务器之间就建立好了连接,并且建立好连接之后,操作系统内核中,就需要使用一定的数据结构来保存连接相关的信息。其中最重要的就是“五元组”,并且客户端服务器都得保存五元组,即源IP、源端口、目的IP、目的端口、协议类型(TCP)。保存信息就需要占用系统资源(内存)~~

等到连接断开了,此时双方保存的连接信息就没有什么意义了,对应的空间也就释放了。

 

 双方各自向对方发送了FIN(结束报文段)请求,并且各自给对方一个ACK确认报文。

三次握手和四次挥手的区别:

三次握手一定是客户端主动发起的(主动发起的一方才叫客户端);

四次挥手,可能是客户端发起的,也有可能是服务器主动发起的。

三次挥手,中间两次能合并;

四次挥手,中间两次有时候合并不了(有时候能合并)。

不能合并的原因:

B发送ACK和B发送FIN的时机是不同的。四次挥手中,B给A发的ACK,是内核负责的。B给A发的FIN是用户代码负责的(B的代码中调用了socket.close()方法,才会触发FIN)。B一旦收到了FIN,立即就会由内核返回ACK,但是执行到用户代码中的close才会触发FIN。取决于用户代码的逻辑,如果这两个操作之间的时间差比较大,就不能合并为一条了,相反如果时间差比较小,这是可能会合并的(延时应答和捎带应答)。

三次握手中,B发送的ACK和SYN都是操作系统内核负责进行的,所以能进行合并。

 关于断开连接,我们需要了解两个比较重要的状态:

CLOSE_WAIT:四次挥手挥了两次之后出现的状态,这个状态就是在等待代码中调用socket.close方法来进行后续的挥手过程。

TIME_WAIT:谁主动发起FIN,谁就进入TIME_WAIT,起到的效果,就是给最后一次ACK提供重传的机会。上图看起来A发送玩ACK后就没有A什么事了,理论上说A就应该销毁连接释放资源了,但是并没有直接释放,而是会进入TIME_WAIT状态等待一段时间,一段时间之后再进行资源和连接的释放。等待的这一段时间,就是怕最后一个ACK丢包!!!如果最后一个ACK丢包了,就意味着B过一会就会重传FIN。(B无法区分是FIN丢了,还是ACK丢了,B就做最坏打算FIN丢了,于是就重传FIN)(假设A在收到FIN之后,发送完ACK就立即释放了连接,当重传的FIN到达A之后,此时就无人能处理这个FIN也就无人能针对这个FIN进行应答了)

扩展知识:TIME_WAIT应该持续多久?

设定的时间是2 * MSL。(MSL表示网络上任意两点之间,传输需要的最大时间)这是时间也是系统上可以配置的参数,一个典型的设置就是60S(经验值)。

2.滑动窗口

为什么要有滑动窗口?

滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高传输效率。

 图中描述了主机A和主机B的通信过程,A每发送一组数据,都需要等待B的ACK,由于确认应答机制的存在,导致了每完成一次发送从操作,都需要等待上个ACK的到达才进行下一次发送操作,这么一来,大量时间都花在了等ACK上了,效率就很低效。

举个例子:

女生A让其男朋友B给他取快递,必须这个快递取回来了才让他取下一个:

A:给我取个韵达的快递~

B:好的~

B去快递超市/菜鸟驿站跑了一趟,把韵达的快递取到了。

A:给我取个顺丰的快递~

B:好的~

B又去快递超市/菜鸟驿站跑了一趟,把顺丰的快递取到了。

A:再给我取个中通的快递~

B:(靓仔无语,靓仔心态崩了,靓仔还不敢说不去)好的~

B:B又去快递超市/菜鸟驿站跑了一趟,把中通的快递取到了。

 上述例子就好比确认应答机制,这样一来,大量的时间就浪费在了取快递的路上,显然靓仔心态也很崩,女生等待的时间也很长~~~~

此时滑动窗口应运而生:

本质上就是“批量的发送数据”,一次发送一波数据,然后一起等一波ACK。

 主机A一次向主机B发送了4组数据,在发送这四组的过程中,不进行等待,这四组都发完了,同一等待ACK。

此时一个等待时间,等待了多组数据的ACK,就把等待多份的ACK的时间压缩成一份了,效率大大提升~~~

由于TCP的保证可靠传输的,可靠传输的灵魂所在就是确认应答,如果没有这个ACK,可靠传输就是一句空话,形同虚设,所以是不得不去等ACK的~

仍然是上述例子,区别在于这里A直接向B一次发送了三个取快递的请求,B一次性取完之后统一到一起回复给A。

 ①、如果一次批量发送数据为N组,统一等待一波,此时这里N称为“窗口大小”。

②、“滑动”的含义:并非把这N组数据的ACK都等到了才继续往下发送,而是收到一个ACK,就继续往下发送一组~

 如图所示:

一次发送了4组数据,1-1000、1001-2000、2001-3000、3001-4000,当1001这个ACK到达之后,就认为1-1000这个数据已经收到了,然后就可以立即发送下一组数据,2001这个ACK到达之后,就认为1001-2000这个数据已经收到了,可以立即发送下一组数据~

随着ACK的接连到来,就接连的发送新的数据,此时这个“窗口”(需要等待的ACK),就在逐渐往后滑动~~~

等待的ACK依次为1001、2001、3001、4001.......依次类推滑动

总的来说,当前这个窗口大小越大,可以认为就是传输速度就越快,窗口大了,同一份时间内等待的ACK就更多,总体的等待ACK的时间就少了。

此时我们忽略了一个很重要的问题:丢包~!!!!

那么在滑动窗口的背景下,如果丢包了,该如何重传呢?

丢包分为两种情况:

(一)ACK丢了

下面来看关于ACK含义的图:

此处只考虑ACK丢了的情况,不考虑发送的数据丢了的情况。

ACK确认序号的特定含义,就保证了后一条ACK就能涵盖前一条。

1001这个ACK意味着1001之前的数据都已经确认收到了,2001这个ACK意味着2001之前的数据也都已经确认收到了,此时假设1001这ACK丢了,2001这个ACK到达了,我们仍可以认为1001之前的数据都已经传达到了。假设一次发送了四组数据,每组数据的大小为1000,初次发送完毕这四组数据后就进入等待ACK的阶段,当1001、2001、3001这三个ACK都没有到达的时候,4001这个ACK到达了,此时我们可以直接将窗户往后挪动四个格子,不用等待前三个ACK的抵达了。

(二)发送的数据丢了

 从图中我们可以看到,主机A同时向主机B传输了7组数据,每组数据大小为1000,1001-2000这组数据并没有顺利到达主机B,而是丢包了,此时进入等待ACK阶段,收到了第一个1001表示已经接收1-1000字节的数据,B在在连续收到三次重复的确认应答后,主机A就会意识到1001-2000这组数据丢了,于是就自动进行1001-2000这组数据的重传。即便A给B已经往后发了7001-8000,这个时候B仍然是在索要1001-2000这组数据。索要若干次之后,主机A就明白了,就触发了重传。

一旦A将1001-2000这组数据重传之后,B收到这组数据,后续的2001-7000这些数据都已经传输过了,不必再进行重传,B发送的ACK直接就会是8001,意味着B向A索要8001开始的数据~

三、流量控制

是滑动窗口的延伸,目的也是为了保证可靠性。

在滑动窗口中,窗口越大,传输速度就越高~~,此时考虑到接收方的接收速率,可能发送方打的贼快,接收方的处理速率和发送速率并不匹配,那么此时接收方就会把新收到的包给丢了。

流量控制的关键,就是能够衡量接收方的处理速度,此处就直接使用接收方缓冲区的剩余空间大小,来衡量当前的处理能力。

 此时发送方A将数据发送到B的接收方缓冲区,B的应用程序,在调用read方法的时候,就是在从接收缓冲区取数据。

这个过程类似于“生产者消费者模型”,A就是生产者,B就是消费者,B的接收缓冲区,就是交易场所。

接收缓冲区存在一定的空间大小,A发送数据,接收缓冲区就会自动填充A发来的数据供B的应用程序读取,剩余空间也在动态变化中,于是乎,如果剩余空间比较大,就认为B的处理能力比较强,此时就可以让A发的更快点,反之则让A发的慢点。

类似于水池注水: 

 剩余空间大,就通知注水方加快注水速度,剩余空间小,就通知注水方减缓注水速度。

那B如何告知A剩余空间有多大呢?

通过ACK报文来告知~~~

TCP报头的16位窗口大小,衡量当前接收方缓冲区剩余空间的大小,发送发收到这个数据之后,就会灵活的调整发送速率(窗口大小)。

虽然TCP报头中的窗口大小只有16位,但是这里的窗口大小不止64K,可以更大——实际上,TCP首部40字节选项中还包含了一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位。

 四、拥塞控制

也是滑动窗口的延伸,也是限制滑动窗口的发送速率。

拥塞控制衡量的是,发送发到接收方,这整个链路之间的拥堵情况。

 A的发送速率,不仅仅受B的接收缓冲区的负作用,还受中间链路的处理能力。

A和B并非直连,而是通过很多很多个节点连接起来的,A发送给B的数据经过这些节点传输至B的接收缓冲区,其间这些节点各自的处理速率并非相同的,又由于节点太多,所以很难对这些节点设备一一衡量。

拥塞控制的处理方案,就是通过实验的方式,逐渐调整发送速度,找到一个比较合适的值。(此处单单考虑中间链路的影响,而暂且不考虑接收方缓冲区的影响,假设接收方缓冲区是固定不变的)

做法:A开始的时候以一个比较小的窗口来发送数据,如果数据很流畅的就到达了B,于是就逐渐加大窗口的大小,如果加大到一定程度之后,出现了丢包现象,这个时候就认为通信出现了拥堵,这个时候再减小窗口大小。通过反复的增大/减小过程就摸到了一个合适的范围,拥塞窗口就在这个范围中不断变化,达到“动态平衡”。

 接下来对图进行分析:

①最开始的时候,取得窗口值非常小,纵轴是1个单位。

②指数增长到一定程度,就会进入线性增长。

③线性增长到一定程度,就会出现丢包,一旦丢包,此时发送方立即让窗口变小(回归到初始的窗口大小)继续重复刚才的指数增长+线性增长的过程。

④期望的最理想的效果,窗口大小在阈值和丢包窗口之间。

⑤指数增长的意义:初始情况下给的窗口太小了,可能合适的值是一个更大的值,通过上述这个过程,就可以更快的接近合适值,因此使用指数增长的方式。

⑥回归到初始窗口大小的意义:如果出现丢包,如果降速太慢,就会持续丢包,这就对了网络通信质量产生了很大的影响,因此一下让窗口回归初始值。

⑦ssthresh阈值就决定了啥时候从指数增长变为线性增长,这个阈值取决于当前发生丢包时的窗口大小的一半。

五、延时应答

相当于流量控制的延伸。

流量控制相当于是控制发送发的发送速率,延时应答,就是在这个基础上,能够尽量再让窗口更大一些~

在注水的例子中,注水的同时也在放水,每次注入水时都会询问当前水池的剩余空间,此处延时应答采用的策略是不立即回应发送方,而是等待一段间隔后回答,在这段时间内,放水的过程一直在持续,放掉更多的水,提供更多的空间。

这个操作就是在有限的情况下,又尽可能的提高了一点传输速率。

六、捎带应答(延时应答的延伸)

以客户端、服务器之间的通信来描述:

 A向B发送请求,此时B收到请求,立即回复一个ACK(对请求做出响应)(由操作系统内核完成),B的上层应用程序对A的请求做出响应(代码执行),此时B又要向A发送代码执行的响应,由于延时应答的存在,B并不会在收到请求的第一时间返回系统内核发送的ACK,而是等待一段时间系统内核对A的请求做出应答,如果此时应用程序代码中返回的响应刚好也要进行回应,时机重合了,就可以把这个ACK和响应数据合二为一进行发送~

 七、面向字节流=》粘包问题

TCP粘包问题指的是:应用层的数据报在TCP接收端缓冲区中,若干个应用层数据报混在一起,分不清独立的数据报了。

客户端发送的数据报到达B之后,就会进行分用,分用意味着把TCP数据报进行解析,取出其中的应用层数据,放到接收缓冲区中,以供应用层序来读取调用。 此时缓冲区中的数据是连续的,服务器在对请求的数据报进行读取操作的时候,并不能很好的区分这些数据分别属于哪个数据报。解决措施的关键就是在应用层协议这里,加入包之间的边界用于区分。例如使用特定字符来规划边界等措施。

八、TCP异常处理

(1)进程终止

在进程毫无准备的情况下,突然结束进程。TCP连接是通过socket来建立的,socket本质上是进程打开的一个文件,文件其实就存在于进程的PCB里面的文件描述符表,每打开一个文件,都在文件描述符表里增加一项,每次关闭一个文件,都在文件描述符表里进行删除一项,如果直接杀死了进程,PCB此时也就没了,里面的文件描述符表更不复存在,此处的文件就相当于自动关闭了。

(2)机器关机

按照操作系统约定的正常流程关机(并非直接按钮关机)正常流程的关机,会给进程一点时间,杀死所有的进程,然后再关机。

(3)机器掉电、网线断开

直接霸王想、按下关机键~

操作系统不会有任何的反应,更不会做任何的处理。

 如果服务器断电,A发送的数据将收不到ACK,A就会进入超时重传的逻辑,重传几次后A认为连接出现了故障,尝试重新建立连接,重连失败,A就放弃连接了,A主动释放和B相关的连接。

如果客户端断电,B不知道是A挂了,还是A过会儿再继续,B就时不时的给A发送一个探测报文(不具备任何意义,单纯为了触发ACK),通过探测报文,发现A不返回ACK了,B就会认为A出现了问题,于是就和上述A一样释放和A相关的连接。

总结:

啥时候使用TCP?啥时候使用UDP?

对可靠性有一定要求的使用TCP;对可靠性要求不高,对于效率要求更高的使用UDP。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在前端面试八股文是指一些经典的面试题目,通常围绕着前端开发的核心知识点展开。这些题目的目的是考察面试者对前端技术的掌握程度和应用能力。根据引用所提到的,前端面试题2023八股文可以包括对响应式设计、自适应方案以及变量声明的区别等内容。此外,引用列举了一些常见的数据类型和对象,也会涉及到对字符串、布尔值、数字、数组、对象、函数等的理解。另外,引用提到的Java面试大集合可能还会包含一些与前端相关的技术栈,比如Spring、Spring Boot等。综合这些信息,前端面试题2023八股文可能会涵盖前端开发的基础知识、技术栈以及面试官感兴趣的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [前端面试题2023八股文(最最最详细)](https://blog.csdn.net/m0_65475272/article/details/131514395)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [2023最新八股文前端面试题 (css、js、h5c3)](https://blog.csdn.net/lipenghao111/article/details/130818908)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [java面试大集合一共485页](https://download.csdn.net/download/wm9028/88268176)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值