《工欲善其事,必先利其器》
我们都知道,在客户端访问服务器时,都需要先建立连接,这个连接遵循着互联网上的一个传输协议,我们称之为 HTTP 协议,即超文本传输协议。该连接是在计算机网络体系的应用层上的协议。
而一个标准的客户端与服务器的请求和响应连接也遵循着一种协议,我们称之为 TCP/IP 协议。每一个请求响应连接都包含着 TCP 连接的三次握手的过程。该连接上存在计算机网络体系的传输层上的协议。
一、HTTP 和 TCP 的关系
1. 两者是架构在不同层面上的不同协议
TCP位于传输层上,仅是单纯的建立客户的与服务器之间的连接,并不涉及任何数据传输;HTTP位于应用层上,用于与服务器的收发数据,包括请求头、请求体、响应头、响应体等;
2. HTTP 是在 TCP 的基础上建立的
- 在确认
TCP连接之后,在这基础之上,客户端和服务端才能进行HTTP数据的传输。
二、TCP 连接的方式
为了建立 TCP 连接,通信双方必须从对方了解如下信息:
- 对方报文发送的开始序号;
- 对方发送数据的缓冲区大小;
- 能被接收的最大报文段长度MSS;
- 被支持的TCP选项;
在 TCP 协议中,通信双方将通过三次 TCP 报文实现对以上信息的了解,并在此基础上建立一个 TCP 连接。
而通信双方的三次 TCP 报文段的交换过程,也就是通常所说的 TCP 连接建立实现的三次握手(Three-Way Handshake) 过程。
三、TCP 三次握手的过程
1. 第一次握手
建立连接时,客户端发送 SYN 包(seq = j)到服务器,并进入SYN_SENT状态,等待服务器确认;其中 SYN:指的是同步序列编号(Synchronize Sequence Numbers)。
2. 第二次握手
服务器收到来自客户端的 SYN 包,必须确认客户端的 SYN(ack = j+1),同时自己也发送一个 SYN包(seq = k),即 SYN+ACK 包,此时服务器进入SYN_RECV状态;
3. 第三次握手
客户端收到来自服务器的 SYN+ACK 包,随之向服务器发送确认包 ACK(ack = k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
四、拓展
- 半连接队列
在三次握手期间,服务器维护一个半连接队列。该队列为每个客户端的 SYN 包(seq = j)开设一个条目,该条目表明服务器已收到 SYN 包,并向客户端发出确认,正在等待客户端的确认包。
这些条目所标识的连接在服务器处于SYN_RECV状态,当服务器收到客户端的确认包时,则会删除该条目,服务器随之进入ESTABLISHED状态。
- BackLog参数
表示内核为响应套接字排队的最大连接个数。即服务器会为半连接队列的每个条目进行重传 SYN+ACK 包,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
注意,每次重传等待的时间不一定相同。
- 半连接存活时间
是指半连接队列的条目存活的最长时间。该时间值是所有重传请求包的最长等待时间的总和,因此我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。
- 四次挥手
对于一个已经建立的连接,TCP 使用改进的四次挥手来释放连接。