TCP 协议的三次握手

TCP 三次握手是一个很经典的问题,这里简单的整理一下 TCP 可以成功完成三次握手的流程。

Socket API 的流程
在进行 Socket 编程的时候,服务器端通常使用 socket、bind、listen 这三个 API 函数创建一个被动套接字,然后通过 accept 函数等待客户端的连接,调用 accept 函数后,程序会进行阻塞等待。

客户端通过 socket、connect 两个 API 函数来创建套接字,并针对服务器端发起连接。

在连接服务器端时,整个工作是网络协议进行完成的,并不是由 accept 和 connect 函数真正去完成的,它们只是网络编程的接口,真正做这些事情的是 网络协议,包括同来发送和接收数据的通信,真正完成工作的也是 网络协议 而并不是 send 和 recv 等相关的 API 函数。

三次握手的过程
上面提到,服务端已经处于 accept 函数的阻塞状态等待客户端的连接,而客户端调用了 connect 函数要连接服务器端了,此时双方开始进行三次握手,整个握手过程对于程序员来说是透明的。也就是说,程序员只需要去调用相关的 API 函数,而不用去关心具体建立连接的细节。

整个建立握手的过程是由客户端发起的,因为服务器是被动等待的状态,不会主动发起和客户端的连接。
1、客户端的协议栈向服务器端发送了 SYN 包,并告诉服务器端当前发送序列号 x,客户端进入 SYNC_SENT 状态;
2、服务器端的协议栈收到 SYN 包之后,向客户端进行 ACK 应答,应答的值为 x + 1,表示对 SYN 包 x 的确认,同时服务器也发送一个 SYN 包,告诉客户端当前我的发送序列号为 y,服务器端进入 SYNC_RCVD 状态;
3、客户端协议栈收到服务器端发来的 ACK 包之后,使得应用程序从 connect 调用返回,表示客户端到服务器端的单向连接建立成功,客户端的状态为 ESTABLISHED,同时客户端协议栈也会对服务器端发送 ACK 包进行应答,应答数据为 y + 1;
4、客户端发送的 ACK 包到达服务器端后,服务器端协议栈使得 accept 阻塞调用返回,这个时候服务器端到客户端的单向连接也建立成功,服务器端也进入 ESTABLISHED 状态。

在第 2 步中,其实完成了两个动作,第 1 个动作是,服务端要向客户端发送一个 ACK 包用以进行确认,第 2 个动作是,服务器端要向客户端发送一个 SYN 包用来和客户端完成同步请求。这两个步骤分别使用了 TCP 协议的 SYN 标志和 ACK 标志,如果发送两个包去完成就会显得多余,因此两个动作实际是在一个包内就完成了。

发布了43 篇原创文章 · 获赞 7 · 访问量 4633

猜你喜欢

转载自blog.csdn.net/qq_46522785/article/details/104998847