TCP/IP面试题

一、TCP连接管理:

1、三次握手

(1)客户端发送SYN, Seq=ISN(c),进入SYN_SENT状态;

(2)服务器发送应答SYN+ACK,ACK=ISN(c)+1, Seq=ISN(s), 因为SYN占用一个字节,所以客户端的数据从ISN(c)+1开始,服务器进入SYN_RCVD状态;

(3)客户端发送ACK,Seq=ISN(c)+1, ACK=ISN(s)+1,进入ESTABLISHED状态.

状态转化图:

TCP/IP面试题_第1张图片

问题1:为什么SYN要占用一个字节?

答1:因为这样,每发送一个SYN,Seq序列号就会自动加1(因为ACK=ISN(c)+1),也就是说接收方可以用来判断是否见过这个SYN段,如果出现丢失,该SYN会被重传。

问题2:为什么要三次握手?

答2:(1)如果是2次:服务端发送的ACK丢失,那客户端会再次发送一个SYN,连接被建立,数据正常传输,关闭连接;此时如果迟到的SYN(可能是第一个,也可能是第二个)到达,那么服务端会认为这是新的连接而重新打开连接;并且,客户端没有收到ACK, 它认为没有建立连接,重新发送SYN而等待连接,此时的服务端却认为已经建立连接,开始传输数据。

(2)4次没有必要:因为第2次与第3次可以合并,因为只是控制位SYN和ACK的区别,没有任何其他负担,这样可以减少时间,也可以降低网络负担。

2、四次挥手

https://blog.csdn.net/wendy_keeping/article/details/76098504

(1)在ESTABLISHED状态,连接的主动关闭方(简称主动方),向对方发送FIN+ACK(Seq=K,ACK=L),然后关闭写(发送),进入FIN_WAIT_1状态,等待ACK和FIN;

(2)连接的被动关闭方(简称被动方)接到FIN, 发送ACK(Seq=L, ACK=K+1)确认应答(K+1作为应答,因为FIN也占用1个字节),然后进入CLOSED_WAIT,此时应该查看自己有没有数据要传,如果有继续发送数据;

(3)主动方接收到ACK, 进入FIN_WAIT_2, 等待FIN;

(4)被动方发送FIN+ACK(Seq=L, ACK=K+1),然后进入LAST_ACK,等待ACK;

(5)主动方接到FIN,发送ACK(Seq=K, ACK=L),然后进入TIME_WAIT,等待2MSL(最大报文生存值);

(6)被动方接到ACK, 关闭连接,CLOSED.

问题1:为什么要四次挥手?

答1:(1)类似三次握手的理由,所以至少要大于等于3次;(2)TCP是全双工,允许单方面关闭连接,也就是半关闭状态,因为一方写完了,不等于另一方也写完了。此时一方虽然关闭了发送连接,但是可以接收,另一方可以发送,所以可以是4次;(3)也可以是3次,如果被动方同时发送了FIN,那么主动方将立即进入TIME_WAIT.

问题2:TIME_WAIT?

答2:(1)保证可靠关闭:如果服务器最后发送的ACK因为某种原因丢失了,那么客户一定会重新发送FIN,这样因为有TIME_WAIT的存在,服务器会重新发送ACK给客户,如果没有TIME_WAIT,那么无论客户有没有收到ACK,服务器都已经关掉连接了,此时客户重新发送FIN,服务器将不会发送ACK,而是RST,从而使客户端报错。也就是说,TIME_WAIT有助于可靠地实现TCP全双工连接的终止。

  (2)让迟来的报文(数据或者FIN等)有足够的时间被识别和丢弃,防止影响新的连接。因为通信双方都将处于TIME_WAIT状态的连接(客户端IP、客户端端口、服务端IP、服务端端口)定义为不可重新使用。假设没有TIME_WAIT,客户发送FIN之后,服务端立即发送了ACK(记为ACK1),但是这个ACK因为某些原因没有及时到达客户;客户重新发送FIN,服务端收到第二个FIN,于是又发送ACK2;于是连接关闭;但是客户又立即发起新的连接,连接建立,但是此时ACK1到达,于是客户端就乱套了。也就是说,TIME_WAIT允许老的重复分节在网络中消逝。

  问题:3:为什么TIME_WAIT时间是2MSL?

答3:MSL是报文传输的最大生存时间,超过MSL的报文将被丢弃,这就是TIME_WAIT设置成2MSL(发送方发送、接收方发送加起来的时间)的原因;MSL比TTL大一些。

相关攻击:

(1)SYN泛洪:

对策:SYN cookies

(2)欺骗攻击:

(3)与路径最大传输单元发现有关:

 

二、TCP超时与重传:

超时重传:https://blog.csdn.net/u014800094/article/details/60591852

TCP每发送一个报文段,就设置一次定时器。只要定时器设置的重发时间到而还没有收到确认,就要重发这一报文段。 
TCP环境

报文往返时间不定、有很大差别
A、B在一个局域网络,往返时延很小
A、C在一个互联网内,往返时延很大
因此,A很难确定一个固定的、与B、C通信都适用的定时器时间

TCP采用了一种自适应算法。这种算法记录每一个报文段发出的时间,以及收到相应的确认报文段的时间。这两个时间之差就是报文段的往返时延。将各个报文段的往返时延样本加权平均,就得出报文段的平均往返时延T。

快速重传:要求接收方一旦接收到乱序报文,则立即发送应答,不得推迟,这是为了让发送方尽快知道;发送方设置重复ACK阈值(比如3),如果同一个ACK包被发送方接收到三次,那么会认定为这个包丢失,发送方重发这个包,不必等到超时重传;没有超过3次不会被重发。这比超时重发更有效率;

相关攻击:(1)DoS攻击:

(2)减慢受害TCP的发送:

 

三、TCP数据流与窗口管理:

窗口控制:每次发送一个窗口大小的数据。接收方的ACK应答可能丢包或者延迟(实际上数据可能已经被正确接收),而发送方不立即重发,可以通过下一次ACK包判断之前的发送是否丢包,从而避免不必要的确认;

滑动窗口控制:发送方滑动窗口内是已经发送但是没有被确认的数据,左边是已经被确认的数据,右边是超出控制范围的数据;接受方窗口内是已经接收但没有确认、处理和存储的数据,左边是已经接收并确认的数据,右边是不能接收的数据;当接收到ACK,窗口随之右移;关闭:窗口左边界右移。当已发送数据得到ACK确认,窗口会减小;打开:窗口右边界右移。当已确认数据得到处理,接收端可用缓存增大,窗口变大;收缩:窗口右边界左移。例如糊涂窗口,RFC不支持,但是TCP必须能处理。

流控制:通过接收方的通告窗口实现。接收方每次ACK都会通知一个自己所能接受的数据大小,发送方则不会发送超过这个大小的数据;如果这个窗口通知丢失,那么发送方会时不时(TCP持续计时器)发送一个窗口探测数据段(仅含一个字节的数据),以获取最新的通知窗口大小;TCP不会停止发送窗口探测,可能会导致资源耗尽(蠕虫tarpit攻击)。

相关攻击:

(1)蠕虫:流量攻击。

(2)针对持续计时器,采用客户端多“SYN cookies”技术。解决方法是:当推断出现资源耗尽时,允许其他进程关闭TCP连接。

 

四、TCP拥塞控制:

https://www.cnblogs.com/wxgblogs/p/5616829.html

慢启动:定义一个“拥塞窗口”,启动时设置窗口大小为1个SMSS(指发送方MSS。三次握手时,双方都会在TCP头部写入MSS选项大小,然后发送方可以选择其中的较小者作为SMSS);每收到一个好的ACK应答(“好的”指的是本次ACK大于之前收到的ACK号),窗口大小以接收方通知的窗口大小(在TCP头部有一个窗口大小字段)和SMSS的较小值来增加窗口;这样会使得窗口大小“指数增长”;

拥塞避免:如果超过慢启动阈值,就进入拥塞避免阶段,转为以比例放大拥塞窗口(“加法增大”)。公式是:cwnd(t+1)=cwnd(t)+SMSS*SMSS/cwnd(t), 全部按照字节数计算, 即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。慢启动阈值随时间变化,在没有丢包时,记为上一次最好的操作窗口估计值。https://www.cnblogs.com/zlingh/p/6161088.html

实际上,TCP通信开始时,并不设置慢启动阈值,而是拥塞控制时才设置为发送窗口的一半。(“乘法减小”)

慢启动+拥塞避免:

超时重发时:慢启动阈值设置为当时拥塞窗口的一半(但是并不小于2 SMSS),窗口大小设置为1个MSS,然后开始慢启动算法(“降低到1,指数增长”);

快速重传:当接收方收到失序数据时,立即返回重复ACK,不能延迟发送。原因在于立即使得发送方尽早知道有失序报文段,并告知其空缺位置。发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。当然也可以同时发送新的数据(SACK)。

根据重复ACK推断的丢包通常与网络拥塞有关,因此伴随快速重传应触发拥塞控制机制。

快恢复:采用快恢复算法时,只有在TCP连接和网络超时时,才采用慢启动。

当收到3次ACK时,会由下面的行为:

(1)慢启动阈值(ssthresh)更新为max(在外数据量/2, 2*SMSS);

(2)启动快速重传,将拥塞窗口(cwnd)设为(ssthresh+3*SMSS);

(3)每接收到一个重复ACK,拥塞窗口暂时增加1MSS(拥塞避免算法);

(4)当接收到一个好的ACK,将拥塞窗口重设为慢启动阈值。

注释:(2)(3)构成快恢复。第(2)步通常会让拥塞窗口降低到之前的一半;每接收到一个重复ACK,就意味着相应的数据包已成功传输(因此新的数据包就由发送机会),拥塞窗口会相应地暂时增大,第(3)步维持拥塞窗口的增大过程,使得发送方可以继续发送新的数据包(在不超过awnd的情况下);第(4)步假设TCP已完成恢复阶段,所以拥塞窗口的临时膨胀也消除了(收缩)。

 

 

随机早期检测(RED):

在网络层,当发生拥塞时,路由器会执行尾部丢弃。这可能会影响到很多条TCP连接,使得这些连接都同时进行“乘法减少”,然后慢启动,导致网络线路上通信量突然减小很多,恢复正常后,又突然增大很多。这就是“全局同步”现象。

为了避免“全局同步”,路由器维持两个队列长度门限,min和max. 

(1)平均队列长度小于min:新到达的分组放入队列;

(2)平均队列长度介于min和max之间:以一定概率丢弃分组;

(3)平均队列长度大于max:丢弃。

这样在检测到网络的早期拥塞征兆时,一定概率P丢弃分组,让拥塞控制只在少量连接上进行。

选择参数:min、max、平均队列长度:

min必须足够大,保证网络有足够的通信量;

max必须足够大,保证一个TCP包往返时间RTT内的队列正常增长仍在max之内。经验表明:max=2min是合适的。

平均队列长度:加权平均。与RTT计算相同。

 

五、在浏览器中输入http://www.sina.com并按回车,知道新浪的网站首页显示在浏览器中,请问:在此过程中,按照TCP/IP参考模型,从应用层到网络层都用到了哪些协议? (参考:https://www.jianshu.com/p/267b71b5b909)

过程:https://www.cnblogs.com/linyx/p/3985160.html

应用层:HTTP:WWW访问协议,DNS:域名解析服务
传输层:TCP:HTTP提供可靠的数据传输,UDP:DNS使用UDP传输
网络层:IP:IP包传输和路由选择,ICMP:辅助IP,提供网络传输中的差错检测,ARP:将本机的默认网关IP地址映射城物理MAC

TCP与UDP的区别:

https://www.cnblogs.com/xiaomayizoe/p/5258754.html

http://baijiahao.baidu.com/s?id=1601404119208961392&wfr=spider&for=pc

 

六、既然有了MAC地址,为什么要有IP地址?

如果用MAC地址连接世界,根据MAC地址无法事先知道位置,那么就得向全世界发送数据,造成巨大的流量浪费。

而且由于没有集约机制,网桥/交换机就得维护一张巨大的表格来维护学习到的MAC地址,最终内存耗尽,无法通信。

有了IP地址,为什么要有MAC地址?

ARP:IP地址是逻辑地址,MAC地址是物理地址,要得到IP地址对应的MAC地址,要用ARP。反过来想,为什么不为主机直接分配IP地址呢?--- 那跟MAC有什么区别。

ARP缓存:减少ARP的大量发送,造成流量浪费。

RARP:将MAC地址翻译成IP地址,例如将打印机等小型嵌入式设备连入网络时。由于嵌入设备没有任何输入接口或DHCP无法获取其IP地址。设备连入网络时,RARP服务器会为其注册MAC和IP地址的对应关系。之后使用设备时,设备向RARP服务器发送类似“我的MAC地址是xxx,请告诉我的IP地址是什么”的请求信息。

 

AIO、BIO、NIO:

https://www.jianshu.com/p/ef418ccf2f7d

 

 

参考链接:

https://blog.csdn.net/wendy_keeping/article/details/76098504

https://www.jianshu.com/p/267b71b5b909

https://www.cnblogs.com/wxgblogs/p/5616829.html

https://blog.csdn.net/u014800094/article/details/60591852 socket编程

你可能感兴趣的:(网络)