【TCP 从面试的角度回答三次握手和四次挥手】

三次握手

在http传输数据前,首先进行TCP连接,通常成为三次握手,在三次握手的过程中,双方是多状态改变的,在面试时,我们应该回答的更详细一些。

先列出每个状态所包含的含义,便于下面描述易于理解
在这里插入图片描述个

图源掘金“帅地”文章

刚开始客户端处于closed状态,服务端处于listen状态。

  1. 第一次握手:客户端给服务端发送一个SYN报文,并指明客户端的初始化序列号SN(seq=x),之后客户端处于SYN-SEND状态。
  2. 第二次握手:服务端收到客户端的SYN报文后,返回自己的SYN,并且指定了自己的初始化序列号ISN(seq=y),同时会把客户端的ISN+1(x+1)作为ACK的值,表示自己已经收到了客户端的SYN,这时服务器处于SYN-RECIVED状态。
  3. 第三次握手:客户端收到SYN报文后,会发送一个ACK报文(y+1),并且指定当前序列号(x+1),也是把服务器的ISN+1作为ACK的值,表示已经收到了服务端的SYN报文,此时客户端处于ESTABLISED状态。
  4. 服务器收到ACK报文后,也处于ESTABLISED状态,此时,双方建立的连接。

四次挥手

要把每个阶段的状态说清楚,不要说的过于简单

刚开始双方都处于ESTABLISED状态,假如是客户端先发起关闭请求

  1. 第一次挥手:客户端发送一个FIN报文,报文中指定一个序列号(seq=x+2),此时客户端处于FIN_WAIT状态
  2. 第二次挥手:服务端收到FIN,会发送一个ACK报文,且把客户端的序列号值+1(x+3)作为ACK报文的序列号,表明已经收到客户端的报文了,此时客户端的处于CLOSE_WAIT状态
  3. 第三次挥手:如果服务器也想断开连接,和客户端第一次挥手一样,发送FIN报文,且指定一个序列号(seq=y+1),此时服务端处于LAST_ACK的状态
  4. 第四次挥手:客户端收到FIN后,一样发送一个ACK作为应答,且把服务端的序列号值+1(y+2)作为自己ACK报文的序列号值,此时客户端处于RIME_WAIT状态。需要过一阵子以确保服务端收到自己的ACK报文之后才会进入CLOSED状态
  5. 服务端收到ACK报文之后,就处于关闭连接了,处于CLOSED状态

面试常问问题:

1.为什么需要三次握手,两次不可以吗
答:第一次握手,客户端发送网络包,服务端收到了,这样服务端确定了客户端的发送能力是正常的;第二次握手,服务端发包,客户端收到了,这样客户端确定了服务端的接收、发送能力时正常的。但是此时服务端不能确定客户端的接收能力;于是第三次握手,客户端发包,服务器收到,服务器确认了客户端的接收发送能力是正常的。
因此,需要三次握手才能确认双方的接收与发送能力是否正常。

2.三次握手的作用:
-. 确认双方的接收与发送能力
-. 指定自己的初始化序列号,为后面的可靠传输做准备

3.ISN(初始化序列号)是固定的吗?
三次握手的重要功能是客户端和服务端的交换,ISN以便让对方知道接下来接收数据的时候如何按照序列号组装数据。如果ISN是固定的,攻击者很容易猜出后续的序列号,因此是动态生成的。

4.什么是半连接队列?
服务器第一次收到客户端的SYN之后,会处于SYN-RECIVED状态,此时没有完全建立连接,服务器就会把这种状态放到一个队列里,这种队列成为半连接队列;如果完成三次握手,就会被放入全连接队列。如果队满了,就可能出现丢包的现象。

5.SYN-ACK重传次数
服务器发送完SYN-ACK包后,如果没有收到客户端确认的包,就会进行首次重传,等待一段时间仍未收到,进行第二次重传,重传次数超过系统规定的最大重传次数,就会将连接信息从队列中删除

6.三次握手过程中可以携带数据吗?
第一次、第二次不可以,第三次可以。
如果第一次可以的话,攻击者可以将大量数据放到第一次握手的SYN中,这会花费服务器很多时间和内存去接收报文,这会让服务器更容易受到攻击。
对于第三次的话,此时客户端已经处于ESTABLISHED状态,对于客户端来说可以建立连接了,并且已经知道了服务器的接收发送能力是正常的了,所以可以携带数据。

7.第一次握手的报文段里除了SYN标志位,还包含什么?
还包含客户端的初始化序列号,是可靠数据传输的关键部分。

8、TCP是怎么保证可靠数据传输的
TCP报文中的首部字段中有序列号和确认号,这两个字段是TCP可靠数据传输的关键部分,假设客户端和服务器已经建立了连接,他们可以向对方发送数据。在双方三次握手时,会随机生成一个初始序号,并告诉对方,接下来传输的数据是从这个序列号开始。而服务端填充进报文里的确认号,是它期望从客户端收到的下一字节的序号,同时服务端也是在通过这个确认号告诉客户端,之前的报文已经收到了。
可靠数据传输的本质是我把报文段发出去,我要知道对方有没有成功接到这个文档,当我发现没有收到时,就要重新发送这个报文段,直到对方确认为止。

9.TCP是一个包发送出去并得到确认后,才可以发送下一包,还是无需等待确认就可以发送下一个包?
TCP允许发送方发送多个报文段而无需等待确认,这些报文就像被填充到一条流水线里,通过流量控制和拥塞控制来判断是否允许发送更多的报文段,一旦“发送,还未确认”的报文数量到达N,N为窗口长度,TCP方就无法再发送下一个报文段。

10.TCP是怎么感知丢包的?如何进行处理的?
第一种情况:定时器超时
TCP发送端会维护一个单一定时器,定时器和窗口绑定,定时器始终监控着窗口中的第一个包的状态,窗口发生变化,就必须重启定时器,定时器超时意味着,当前窗口最前面的包丢失了,此时发送端会重传具有最小序号但仍未被确认的报文段
第二种情况:收到冗余ACK
比如ACK0,ACK1发送接收完毕。报文2丢失了,接收端收到序号3,4,5的报文段时,统一回复了ACK1,这几个ACK1就是冗余ACK。当TCP接收端收到比期望序号大的失序报文时,会立即发送冗余ACK,对最后一个按序的报文段就行确认,将冗余ACK的确认号置为期待的下一个按序的序号,在定时器过期之前,发送端连续收到3个ACK1,发送端就会意识到,这个被冗余确认了3次的报文段后面的报文段已经丢失了,这时TCP会进行快速重传,即不用等到定时器过期,立即重传丢失的报文段。

11.第四次挥手时,为什么客户端发送ACK之后不直接关闭,而是要等一阵子才关闭
要确保服务器已经收到ACK报文,如果没有收到的话,服务器端会重发FIN报文,客户端再次收到ACK报文时,就知道之前的ACK丢失了。客户端再次发送ACK报文。TIME_WAIT持续的时间至少是一个报文的来回时间,一般会设置一个计时,如果过了这个计时没有再次收到FIN报文,则代表对方成功就是ACK报文,此时客户端会处于CLOSED状态。

12.TCP和UDP的区别?
TCP和UDP都在传输层中
TCP协议面向有连接,能正确处理丢包,传输顺序错乱的问题,但是为了建立和断开连接需要至少7次的收发包,资源浪费。
UDP面向无连接,不管对方有没有收到,如果想要的到通知,需要通过应用层。

注:本文整理于掘金“帅地”文章

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值