三次握手过程
- 客户端发送一个同步(SYN)包给服务器,携带一个随机生成的序列号x,表示请求建立连接。
- 服务器收到SYN包后,发送一个带有自己的序列号y和确认号x+1的SYN-ACK包给客户端,表示接受连接请求。
- 客户端收到服务器的SYN-ACK包后,发送一个确认(ACK)包给服务器,确认号为y+1,表示连接建立成功。
gherkin
客户端 服务器
| SYN = x |
|----------------->|
| |
| SYN = y, ACK = x+1 |
|<-----------------|
| |
| ACK = y+1 |
|----------------->|
三次握手的目的
第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
第二次握手:服务端发包,客户端收到了。 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
四次挥手过程
gherkin
客户端 服务器
| FIN = x |
|----------------->|
| |
| ACK = x+1 |
|<-----------------|
| |
| FIN = y |
|----------------->|
| |
| ACK = y+1 |
|<-----------------|
| |
| FIN = z |
|----------------->|
| |
| ACK = z+1 |
|<-----------------|
- 客户端发送一个关闭连接请求(FIN)给服务器,其中携带一个序列号x。
- 服务器收到FIN包后,发送一个确认(ACK)包给客户端,确认号为x+1。
- 服务器向客户端发送一个关闭连接请求(FIN)包,携带一个序列号y。
- 客户端收到服务器的FIN包后,发送一个确认(ACK)包给服务器,确认号为y+1。此时客户端进入TIME_WAIT状态,等待可能出现的延迟数据报文。
服务器收到客户端的ACK包后,关闭连接。
挥手为什么需要四次
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。