一、建立连接(三次握手)
TCP是基于链接的协议也就是说在正式收发数据前必须和对方建立可靠的连接,一个TCP连接必须经过三次握手才能建立起来。
步骤如下:
1) 为了建立连接,客户端发送SYN包(SYN=j)到服务器B,进入SYN_SEND状态,等待服务器B确认(通俗讲就是,A向B请求连接:“我想给你发数据,可以吗?”)
2)服务器B收到SYN包,必须确认客户端A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k)即向客户端发送SYN+ACK包,此时服务器进入SYN_RECV状态(通俗讲,就是B回应A:“好吧,你来吧”)
3)客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B完成三次握手,进入ESTABLISHED状态,开始正式发送数据。
二、关闭连接(四次分手)
由于TCP连接是全双工的,每个方向都必须进行单独的关闭,这个原则表现为当一方完成它的数据发送任务之后就能发送一个FIN来终止这个方向的连接,因此收到一个FIN只是意味着一个方向上没有数据流动,一个TCP连接在收到一个FIN之后仍然能发送数据,首先进行关闭的一方将执行主动关闭,而另一方将执行被动关闭
1)客户端A发送一个FIN给服务器B,用于关闭客户端A到服务器B的数据发送(A对B说:“我传完了”);
2)服务器B收到这个FIN,他发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号(B回应A说:“好的”);
3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(B对A说:“我也传完了”)
4)客户端A发回ACK报文确认,并将确认序列设置为收到的序号加1.(即A回应B说:“好的,我收到了,我撤了”)
为什么TCP建立连接是三次握手,而关闭连接却是四次握手呢?
因为服务端的Listen状态下的SOCKET当收到SYN报文的建连请求后,它可以把ACK和SYN(ACK起应答作用而SYN起同步作用)放在一个报文里发送,但是在关闭连接时,当服务端收到FIN报文通知时,它仅仅表示对方(客户端)没有数据需要发送给你了,但是并不表示对方的所有数据你都已经接收到或者说你所有的数据都已经发送给对方了,所以你可能未必想立即关闭Socket,因此再次发送FIN包给客户端通知它可以关闭连接,客户端只有同时接收到ACK与FIN才会关闭客户端到服务端的连接。