之前的我们讲过收发数据大致分为四个阶段:
(1) 创建套接字(创建套接字阶段)
(2) 将管道连接到服务器端的套接字上(连接阶段)
(3) 收发数据(通信阶段)
(4) 断开管道并删除套接字(断开阶段)
数据收发操作的第一步是创建套接字。一般来说,服务器一方的应用程序在启动时就会创建好套接字并进人等待连接的状态。客户端则一般是在用户触发特定动作,需要访问服务器的时候创建套接字。在这个阶段,还没有开始传输网络包。
创建套接字之后,客户端会向服务器发起连接操作。首先,客户端会生成一个SYN为1的TCP包并发送给服务器。这个TCP包的头部还包含了客户端向服务器发送数据时使用的初始序号,以及服务器向客户端发送数据时需要用到的窗口大小。当这个包到达服务器之后,服务器会返回一个SYN为1的TCP包。这个包的头部中也包含了序号和窗口大小,此外还包含表示确认已收到包的ACK号。当这个包到达客户端时,客户端会向服务器返回一个包含表示确认的ACK号的TCP包。此时,连接操作就完成了,双方进入数据收发阶段。
数据收发阶段的操作根据应用程序的不同而有一些差异,以Web为例,首先客户端会向服务器发送请求消息。TCP会将请求消息切分成一定大小的块,并在每一块前面加 上TCP头部,然后发送给服务器。 TCP头部中包含序号,它表示当前发送的是第几个字节的数据。当服务器收到数据时,会向客户端返回ACK号。在最初的阶段,服务器只是不断接收数据,随着数据收发的进行,数据不断传递给应用程序,接收缓冲区就会被逐步释放。这时,服务器需要将新的窗口大小告知客户端。当服务器收到客户端的请求消息后,会向客户端返回响应消息,这个过程和刚才的过程正好相反。
服务器的响应消息发送完毕之后,数据收发操作就结束了,这时就会开始执行断开操作。以Web为例,服务器会先发起断开过程。在这个过程中,服务器先发送一个FIN为1的TCP包,然后客户端返回一个表示确认收到的ACK号。接下来,双方还会交换一组方向相反的FIN为1的TCP包和包含ACK号的TCP包。最后,在等待一段时间后,套接字会被删除。