三次握手,四次挥手可以说是炙手可热的面试题了,来看看它究竟长什么样子吧!
我们先把流程图贴上来 :
为什么这么复杂? 因为TCP是可靠性传输。
确认可靠传输的前提: TCP连接管理机制
用TCP首部控制的字段来管理TCP连接 :
三次握手(建立连接) : 两次连接请求(SYN)+两次应答(ACK)
流程 : 服务端进入LISTEN状态后,客户端向服务端发送SYN连接请求,服务端收到后会发送ACK应答和SYN连接请求,客户端收到后再向服务端发送ACK应答,此时连接建立成功。
四次挥手(断开连接) : 两次断开请求(FIN)+两次应答(ACK)
流程 : 主动断开方不确定,主动断开方发送FIN断开请求,被动方回复ACK应答进入CLOSE_WAIT状态,被动方关闭连接后再发送FIN断开请求,主动断开方回复ACK应答进入TIME_WAIT状态,被动方收到ACK后关闭,2MSL后主动方关闭,此时连接断开成功。
Q1: 为什么服务端要先进入LISTEN状态?
A1: 在应用层就是调用listen函数,使socket变为被动状态,允许其他客户端和服务器建立连接。
Q2: 怎么才算建立连接成功?断开连接成功?
A2: 两端都进入ESTABLISHED状态,都进入COLSED状态。
Q3: 为什么要有TIME_WAIT状态,直接关闭不好吗?
A3: 重传控制 , 为了保证最后一个ACK丢了还能重传,确定对方确认。客户端进程已经没有了,但是TCP连接还存在,如果被动方没收到ACK,就会超时重传FIN,这样
Q4: 为什么是2MSL?
A4: 连接存在就会占用内存,所以不可能一直存在,等2MSL就会强制中断。
1.保证被动方可以超时重传FIN
2.MSL是一个数据报从一端走到另一端所消耗的最长时间,2MSL能保证两个传输中未被接收或者迟到的报文段消失(否则如果服务器立刻重启,会收到上一进程的数据,此时信息可能错误)
Q5: 为什么是三次握手,四次挥手?
A5: 三次握手是因为服务端接收到SYN后,可以直接发送SYN和ACK应答用来同步。
服务器收到FIN后,内核主动回应ACK,应用层调用了close才会发送FIN。也可以是三次挥手,用捎带应答。
Q6: 如果客户端突然出现故障怎么办?
A6: TCP处理异常设有保活定时器: 如果一定时间内没有收到任何发送方的数据,此时就发一个心跳包,发若干次后,如果没回应就断开连接。
Q7: 为什么不能用两次握手或者四次握手?
A7: 三次能确保对方具有收发数据的能力。
如果是两次,客户端给服务器发消息,服务器收到后再给客户端发消息,不能确保客户端是否能收到消息。所以需要客户端再回复给服务器表示我能收到消息。
四次也就多余了。