一:TCP的三次握手
建立TCP需要三次握手:客户端发送连接请求,服务器确认,客户端再次确认。
第一次握手:客户端发送连接请求,该TCP请求的首部,SYN标志位1,并且随机产生一个seq=x,并将该数据包发送给Server。
第二次握手:服务器回应,Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个seq=y,并将该数据包发送给Client确认连接请求。
第三次握手:客户端确认,若接受到的ACK=1且ack是x+1,那么发送ACK=1,ack number为服务器的seq = y+1。
二:为什么TCP连接需要三次握手,两次为什么不可以
防止实效的链接请求报文段被服务器接收,从而造成服务端资源的浪费。
失效的链接请求:若客服端向服务端发送的连接请求丢失,客户端等待应答超时后就会再次发送连接请求,此时,上一个连接请求就是失效的。
若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。
此外3次是双方都回复ack条件下的最少次数,减少网络控制数据量。sctp(流控制传输协议),hip(主机标志)等协议使用4次握手,增加cookie传递,防止syn攻击。
三:TCP的四次挥手
断开连接需要四次挥手。我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接,任意一方都可以要求断开连接。
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
四:为什么建立连接需要三次而断开连接需要四次
对于断开连接,考虑TCP是全双工的,双方同时可以发送和接收。第一次挥手表示客户端不再发送了。第二次挥手表示服务器知道你不发送了,所以服务器就不接收了,但是服务器可能还需要发送,所以客户端不能一次性把发送和接收都关闭了,需要等着服务器也不发送了(第三次挥手)才能把接收也关闭了(第四次挥手)