Java后台开发面试经验(二)

感谢牛客网网友提供的面试经验!

1. 解释一下TCP三次握手四次挥手

图片来源:https://www.jianshu.com/p/29868fb82890
在这里插入图片描述
答: 嗯…(稍作思考),TCP协议是一种可靠的协议,在正式传输数据之前必须通过三次握手建立连接并且互相交换窗口大小。在传输结束之后,通过四次挥手来确认双方都结束数据交互

  • 三次握手详细来说,在数据传输开始前:
    第一次握手客户端向服务端送一段SYN标记的包来请求连接
    第二次握手服务器端接收之后,确认客户端发送数据能力正常。并返回一段SYN+ACK
    第三次握手客户端接收之后,明确了从客户端到服务器的数据传输正常的,并返回最后一段ACK给服务端
    三次握手完毕后,客户端与服务器才正式开始传送数据。

  • 四次握手详细来说,在数据传输结束后:
    第一次挥手客户端发送一个FIN包,用来关闭客户端到服务端的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据。
    第二次挥手服务端收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号, SYN 和 FIN 都有seq序号)。
    第三次挥手服务端发送一个FIN,用来关闭服务端到客户端的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
    第四次挥手客户端收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1
    至此,完成四次挥手,客户端与服务器才正式结束数据传输。

二. 解释一下SYN、ACK 、FIN

  • 确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

  • 确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

  • 同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

  • 终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

  • PS:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。

原文链接:https://blog.csdn.net/qq_38950316/article/details/81087809

三. 为什么是三次握手,可以是两次吗?

不可以(非常坚定的语气)。假如以两次握手建立连接,服务端在某一时刻突然收到了一个来自被客户端卡了很久已经丢弃的SYN包,服务端的操作是返回SYN+ACK并且进入工作状态。客户端收到反馈后,无法告诉服务端这是错误的SYN的包,会造成资源的浪费

四. 为什么断开连接需要四次挥手?

答:因为在客户端发送给服务端FIN包后,服务端返回的FIN和ACK包是分开发送的。为什么要分开呢?因为客户端发送给服务端FIN包后,只表示客户端已经没有数据要发送了,但是另一个方向上可能还会有数据传输进来。所以第二次和第三次挥手分开发送,服务端先给出ACK确认信号,表示已经收到FIN请求,然后当自己也可以结束的时候,再次发送FIN信号。是为了为未传输完毕的数据预留时间,所以需要挥手交互需要四次。