TCP传输协议与UDP协议不同,它是面向连接的安全的传输协议,面向连接说明TCP需要在传输数据之前进行连接,就好比我们打电话通话前要进行拨号一样。
在说明三次握手以及四次挥手之前,先来说明下一些标志:
SYN:同步序号,发送表示要请求一个TCP连接请求
FIN:发送端完成发送任务(但仍可以接受报文)
ACK:确认序号有效
ISN:序列号
一.三次握手
上图中,
第一次握手:客户端发送一个SYN段指明其打算连接的服务器的端口,以及一个客户端初始序列号X以请求一个TCP连接
第二次握手:服务端收到客户端的请求后,也向客户端发送一个SYN报文并发送服务端初始序列号为Y作为应答,同时将确认序列号设置为客户的初始序列号X+1以对客户端的SYN报文段进行确认。
第三次握手:客户端将服务端的初始序列号Y+1作为确认序列号发送给服务端。至此三次握手完毕。
二.四次挥手
建立一个连接需要三次握手,而终止一个连接需要经过四次握手。这是因为TCP连接是全双工的(即数据在两个方向上都能同时传递),因此每个方向都需单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的链接。当一端收到一个FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。收到一个FIN只意味着在这一方向上没有数据流动。一个TCP连接在收到一个FIN后仍然能发送数据,一个TCP连接在发送一个FIN后仍然能接受数据。
上图中,当服务器接受到客户发送的FIN时,它发回一个ACK,确认序号为收到的序号加1(M+1)。同时服务器发送一个FIN,序号N给客户端以关闭它的连接。客户必须发回一个确认以及一个确认序号(ACK,N+1)。
三.question.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
——即在三次握手建立连接时,将ACK与SYN报文段一起发送不会引起问题;但在四次挥手时,如果将FIN与ACK报文一起发送则会引起问题,因为在收到FIN时仍可能有数据要发送,如果一起发送则该数据就发送不了了。