三次握手
1、客户端主动打开连接,服务端被动打开连接
2、为何需要“第三次握手”做确认,按照一般的逻辑你发送我确认就可以了,不需要再次确认。这里主要是为了防止已经失效的报文又传给服务端:
下面以只有两次握手举例:
client第一次发送连接请求给server,但是由于网络情况,超时,于是client再次发送连接请求给server
server接收到client第二次发送的连接请求,于是发送确认连接报文给client,这样按照两次握手的协议,连接建立。过会,连接释放,client和server关闭连接。
这个时候,client第一次发送的连接请求报文经过辗转周折到达了server,server一看是client发送的,以为client又再次发送建立连接请求,于是正常的发送确认报文给client,连接建立。但是,实际上这个时候,client已经不需要建立连接了,对于server发送的确认报文就不理不睬(丢弃),这样就造成了server端连接打开,资源被占用得不到释放的情况。所以为了防止这种情况,在client收到server发送过来的确认报文后,client会再次发送一次确认报文给server。
3、整个过程,server端进入收听状态,client发送连接建立请求报文,并进入同步-已发送状态,server收到报文同意建立请求,向client发送连接建立确认报文,并进入同步收到状态,client收到报文后发送确认报文给server并已建立连接状态,server收到client发送的确认报文也进入已建立连接状态。
四次握手
TCP连接的释放共需要发送四次报文,双方都可以向对方发送连接释放报文,这点与建立连接不同。
现在假设client和server都处于连接已建立状态,下面准备释放连接:首先A向B发送连接释放报文,并停止发送数据给B,主动关闭TCP连接,A进入终止等待1的状态。B收到连接释放报文后,发出确认报文,B进入CLOSE-WAIT(关闭等待)状态。此时,从A到B这个方向的连接就释放了。**TCP连接处于半关闭状态。即A已经发完了,但B可能还有数据,A仍要接收。A收到来自B的确认后,就进入FIN_WAIT_2(终止等待),等待B发出的连接释放报文。若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这是B发出连接释放报文,B进入LAST-ACK(最后确认)状态,等待A的确认。A收到B的连接释放报文段后,发送确认报文给B,同时进入TIME-Wait(时间等待)状态。但需要注意的是,此刻连接尚未完全释放,需要等A由TIME_WAIT状态进入到CLOSED状态,B收到A发送的确认报文,进入CLOSE状态。一般B会在A前面进入CLOSE状态,换句话将,等A进入CLOSE状态整个连接才得到释放。
A由TIME_WAIT进入到CLOSED状态需要等待2MSL(最长报文段寿命),这个是为了避免如三次握手中有延迟报文请求到B中。(2MSL确保由A同一时间发送的报文都会从网络中消失)
TCP保活计时器,为了防止客户端意外,服务端连接一直被占用,一般每隔2小时,服务端需要确认客户端的状态。如果2小时内没有收到客户的数据,服务器就发送一个探测报文,以后每个75分钟发送一次,若一连10个客户端无响应,则认为客户端出了问题,关闭该连接。