您的位置:首页 > 理论基础 > 计算机网络

TCP : 3次握手与4次挥手

2016-06-07 17:02 573 查看
TCP协议在运输层工作,当客户端想要连接服务器,TCP协议要求 客户端和服务器共需要3次数据传输,才能确保客户端和服务器已经连通,我们把这个过程称为——3次握手。

为什么是3次握手呢?我先来举一个现实中的例子。我给你打电话时,当拨号过去时,相当于我发送了第一次握手,表示我想和你通话。当你提起电话,“喂?”,这是你发送的第二次握手,发送消息给我,表示愿意与我通话,并且你信号正常。我这边再次“喂”,这是我发出的第三次握手,表示我收到了你的确定通话的消息,并且我这边信号也正常。 到此时,连接建立成功,开始聊天。

这三次握手必不可少(也不必多),第一次建立连接,第二三次,双方互相确认连接。3次成功握手之后,双方才算成功的建立信息连接。

在讲解3次握手原理之前,首先得了解TCP进行数据传输时发送的头结构。



TCP在每次发送信息时,就是这样的一个头结构文件。其中包含:

TCP源端口(自己的端口号),和TCP目的端口(要发送到哪个端口);

TCP序列号,TCP应答号;

数据偏移量(指示何处数据开始);

保留位 (为将来新的用途所保留);

标志位(URG 紧急标志,ACK 有意义的应答标志,PSH 推,RET 重置连接标志,SYN同步序列标志,FIN 完成发送数据标志);

窗口 用来表示想收到的每个TCP数据段的大小;

校验和 (加密机制);

紧急指针 指向后面是优先数据的字节,在URG标志设置了时才有效;

最值得注意的是,SYN 与 ACK,这是3次握手的关键!

第一次握手:确认目的设备存在于网络上;

建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;

第二次握手:确认目的设备有活动的服务,并且正在源客户端要使用的目的端口号上接受请求;

服务器收到SYN包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:通知目的设备源客户端想要在该端口号上建立通信会话;

客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器ESTABLISHED(TCP连接成功)状态,完成三次握手。

过程如图所示:







总结:首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。

三次握手实现如下图:



3次握手信息从中间开始:

9点48分 本机 7070端口发送消息给5050端口想要建立连接。序列号为 seq:1443350267

9点48分 5050端口给7070,发送消息,同意建立连接。注意发送给了143350268,是上一个序列号加1,原因请看上边分析。

9点48分 7070端口回复消息给5050,确定连接建立。3次握手完成。

—————————————————————————————————————————————

说完TCP建立连接的3次握手过程,就不得不说TCP断开连接的4次挥手过程。

4次挥手简单来说:

A给B说,我要跟你断开连接(1次),B回复A,同意,你断开吧(2次)——A到B的连接断开

B给A说,我也要和你断开连接(3次),A回复B,同意,你也断开吧(4次)——B到A的连接断开

有人可能会问A到B都断开了,A后来怎么给B回的消息,应答断开并不是真正的断开,这个下面解释。

过程如图所示:



Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说”我Client端没有数据要发给你了”,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,”告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息”。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。

当Server端确定数据已发送完成,则向Client端发送FIN报文,”告诉Client端,好了,我这边数据发完了,准备好关闭连接了”。Client端收到FIN报文后,”就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。

“Server端收到ACK后,”就知道可以断开连接了”。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!

(等2MSL时间的原因:因为网络原因,主动关闭的一方发送的这个ACK包很可能延迟,从而触发被动连接一方重传FIN包。极端情况下,这一去一回,就是两倍的MSL时长。)

问题:为什么TCP建立连接需要3次,而断开连接需要4次?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要4次挥手!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  tcp 服务器 数据 工作