图解:TCP三次握手与四次挥手

计算机网络 TOMORROW 2年前 (2018-07-08) 696次浏览 1个评论 扫描二维码
 西邮 Linux 兴趣小组 
通过 TCP/IP 协议的学习,我们可以知道 TCP 协议是一种面向连接的、可靠的传输协议。其中,“三次挥手”是为了保证客户端与服务器连接的有效性;而“四次挥手”则是为了保证连接的正确断开。
TCP 状态
SYN —— 同步序列编号,在建立连接时发送。ACK —— 确认信息,在确认 SYN 信息时发送,响应信息。

FIN —— 关闭连接。

RST —— 连接重置。

PSH —— 有数据传输。

URG —— 紧急指针字段值有效。

三次握手
建立 TCP 连接时会经过如下步骤:1.服务器准备接收客户端连接(通过 socket API),由于连接是由客户端激发的,因此称为被动打开。

2.客户端调用 connect 开始主动打开,并发送 SYN(syn = i)包,告诉服务器发送数据的序列号。

3.服务器确认(ACK , ack = i+1)客户端发来的信息(SYN),并发送 SYN(syn = j),其中含有服务器发送数据的初始序列号。注:SYN 和 ACK 是同时发送的,在一个数据包中。

4.客户端确认服务器发送的 SYN,发送 ACK(ack = j+1)数据包。

其中,因为 SYN 需要占据一个字节的序列号空间,因此 ACK 中确认号为发来的 SYN 序列号加 1;类似,FIN 的 ACK 确认号为该 FIN 序列号加 1。

图解:TCP 三次握手与四次挥手
四次挥手
TCP 挥手关闭连接时会经过如下步骤:1.某进程先调用 close,该端 TCP 发送 FIN(fin = i),表示数据发送完毕,需要关闭连接,称为主动关闭。

2.接收到 FIN 的对端执行被动关闭。进行确认(ACK , ack = i+1),在该进程接收的其他所有数据之后添加文件结束符(end-of-file)。

3.一段时间之后(因为要处理已经接收到的数据),接收到文件结束符的进程调用 close 关闭套接字,这导致它的 TCP 也发送 FIN(fin = j)。

4.主动关闭连接的一端确认(ACK , ack = j+1)最后发送的 FIN。

图解:TCP 三次握手与四次挥手
两个小问题

1. 为什么建立连接要三次握手,而断开连接要四次挥手?

建立连接时,因为发起连接的一端在发出请求后,连接建立之前就不会再发出任何数据,因此接收连接请求的对端可以将 ACK、SYN 放在一个数据包里发回给请求端,即需要三次数据发送。而断开连接时,在一端主动断开连接并发送 FIN 包后,对端接收到发来的 FIN 包,进行确认(ACK),然而此时服务器可能还在给另一端发送数据,只有在数据发送完后才能断开连接,发送 FIN 包(所以不能像三次握手时那样将 ACK、SYN 同时发送),另一端收到 FIN 后再进行确认并发送 ACK,因此需要四次数据发送。TCP 建立的连接为全双工通道,可以双向传输数据,因此在建立连接、断开连接时,需要两端都要进行请求与确认。

2. 为什么建立连接的 ACK、SYN 可以同时发送,而断开连接则需要分开发送?
建立、断开连接都需要两次请求与确认,只是建立连接时 SYN、ACK 可以同时发回,而在断开连接时,由于被动关闭的一端可能还会发送数据,只有数据发完后才能发送 ACK,所以只能分开发送,也就造成了建立连接为三次,断开连接反而成了四次(建立连接时由于握手期间连接未完全建立,故不能发送其他数据)。

TOMORROW 星辰 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:图解:TCP 三次握手与四次挥手
喜欢 (0)
TOMORROW
关于作者:
一个从石头坑掉到泥坑里的攻城狮。
无私的微笑发表我的评论  请填写正确的 个人信息
取消评论
表情 加粗 斜体 签到
(1)个小伙伴在吐槽
  1. 好文章!666,学习了
    草民电影网2019-05-05 20:33 回复 Windows 7 | 未知浏览器