@[toc]
前言
主要介绍为什么TCP协议需要三次握手和四次挥手
TCP协议的介绍
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议.
- 面向连接(可靠传输)
- 确认,流量、差错控制、定时
- 可靠按序交付
- 不支持多播和广播,开销大
- TCP连接是基于字节流的
- 传输的数据单位是TCP报文段
三次握手
TCP连接的建立:三次握手
- 使每一方确认对方的存在
- 允许双方进行参数的协商
- 进行资源的分配
标志位:
- SYN: Synchronize Sequence Numbers,同步序列编号
- ACK: Acknowledge Character,确认字符 (不同与ack) 关键字:
- seq:Sequence Number,序列号 代表本条消息的序列号 (按序交付)
- ack:期待下一次收到的序列号,一般为seq+1
三次握手流程:
- ==A== 的 TCP 向 ==B== 发送 ==连接请求==报文段,其首部中的同步位 ==SYN = 1== ,并随机选择一个序号 ==seq = x== ,表明传送数据时的==第一个数据字节序号==为 ==x==。
TCP 协议规定,==SYN 置 1 的报文段不能携带数据==,但是要消耗一个序号
- B 的 TCP 收到==连接请求==报文段后,如果同意,则发挥==连接同意==报文 B 在连接同意报文段中应使 ==SYN = 1== ,使 ==ACK = 1== 其确认号==ack = x + 1== ,自己随机选择一个序号==seq = y==
3. ==A== 收到此报文后向 ==B== 给出确认,其 ==ACK = 1== ,确认号 ==ack = y + 1==,==seq = x + 1==
A 的==TCP==通知上层应用进程,连接已经建立
4. B 的 TCP 收到主机A的确认后,也通知其上层应用进程:TCP连接已经建立
TCP 为什么需要三次握手?而不是两次?
不是两次的主要原因使为了防止多次连接导致连接混乱。 比如A 主机的网络较差,连续发送了多个连接请求,B收到请求后给予想用,但是B不知道A是否收到了同意连接请求,就只能重复同意,这些过期的请求可能回导致网络的混乱 所以设计成三次握手的情况,客户端在接收到服务端SEQ+1的返回消息之后,就会知道这个连接是历史连接,所以会发送报文给服务端,告诉服务端。 所以三次握手的原因就是==避免多次建立重复连接==
那可不可以是四次,五次或者更多次?
可以,但是没有必要,三次已经足够适应需求了,多次的握手可能导致了资源的浪费
四次挥手
TCP连接的释放:双向释放(4次挥手)
首先解释为什么需要四次挥手?
TCP是基于==全双工通信的==,所以双方都可以主动释放连接。 四次挥手的意义就在于,当 A 发送完最后一条数据之后,但可能B还有未发送给A 的数据。 所以==A在发送完收据后可以请求释放连接==,此时B给与A响应,告诉A我知道你想断开连接,此时==A还可以继续接收B发送的信息==。 在B处理完工作后,也请求释放连接。A同意后,就断开连接。 这样可以保证数据正常可靠的交互。
四次挥手流程:
FIN : 标志位,请求关闭连接
TCP 的标准规定,==FIN==报文即使不携带数据信息,也需要消耗一个==seq==
- 数据==传输结束==后,通信双方都可以释放连接 现在假设==A==向==B==已经发送完数据,A就可以发出==连接释放==报文段,并停止在发送==数据==,主动关闭TCP连接 A 把连接释放报文首部的 ==FIN = 1==,其序列号 ==seq = u==,等待 ==B== 的确认。 ==u 为 A ==已传送数据的==最后一个字节==的序号==加1==
2. B收到后。发出==确认==,意思我收到了,==ACK = 1==,确认号 ==ack = u+1==,而这个报文段自己的序号为==seq = v==
==从A 到 B ==这个方向的连接就释放了,TCP 连接处于==半关闭状态==。B 若发送数据,==A仍需要接收==
- 当B==发送完数据==后,就可以==释放连接==。 B 发出的==连接释放==报文 的== FIN = 1== ,序号为w,==ack仍为u+1==
- A 收到连接释放报文后,必须发出==确认==。==ACK = 1 ==,确认好 ==ack = w +1==,序号==seq = u+1==。
至此,双方断开连接