摘自:《深入理解计算机网络》 王达著 机械工业出版社
相关知识链接
1. IPV4数据报头部格式
2. IPv6数据报头部格式
3. IPv4数据报的封装与解封装
4. IPv4数据报的分段与重组
5. ARP协议报文格式及ARP表
6. ARP地址解析原理
7. ICMP协议及报文格式
8. IPv6协议族的其它协议
9. TCP的主要特性
10. TCP的套接字
11. TCP端口
12. TCP连接状态转移
TCP传输的建立(三次握手)
TCP是一个面向连接的传输层协议,因此,无论哪一方向的另一方发送数据,都必须先在双方之间建立一条传输连接。本文将详细讨论一个 TCP 传输连接是如何建立的。
单方主动连接的TCP连接建立过程
TCP/IP 体系结构中的 TCP 也是使用三次握手机制来建立传输连接的,这与在本章前面介绍的 OSI/RM 体系结构中传输层为了避免重复连接而采取的三次握手机制是一样的,具体流程如下图所示。其实,整体过程在上一篇博客TCP连接状态转移中有全面体现,这里只是单独把 TCP 传输连接建立过程列出来而已。具体步骤如下:
- 首先是服务器初始化的过程,从 CLOSED (关闭)状态开始通过顺序调用 SOCKET、BING、LISTEN、和 ACCEPT 原语创建 Socket 套接字,进入 LISTEN (监听)状态,等待客户端的TCP传输连接要求。
- 客户端最开始也是从 CLOSED 状态开始调用 SOCKET 原语创建新的 Socket 套接字,然后在需要再调用 CONNECT 原语时,向服务器发送一个将 SYN 字段值置1(表示此为同步数据段)的数据段(假设初始序号为 i),主动打开端口,进入 SYN SENT (已发送连接请求,等待对方确认)状态。
- 服务器接收到来自客户端的SYN数据段后,返回一个 SYN 字段置1(表示此为同步数据段)、ACK 字段置1(表示此为确认数据段)、ack (确认号) = i + 1 的应答数据段(假设初始序号为 j),被动打开端口,进入到 SYN RCVD (已经接收到一个连接请求,但未进行确认)状态,注意,确认号是 i + 1, 不是 i,表示服务器希望接收的下一个数据段序号为 i + 1。
- 客户端在收到来自服务器的 SYN + ACK 数据段后,向服务器发送一个 ACK = 1(表示此为确认数据段)、序号为 i + 1、ack = j + 1 的确认数据段,同时进入ESTABLISHED(连接建立)状态,建立单向连接。要注意的是,此时序号为 i + 1, 确认好为 j +1,表示客户端希望收到服务器的下一个数据段的序号为 j + 1.
- 服务器在收到客户端的 ACK 数据段后, 进入 ESTABLISHED 状态,完成双向连接的建立。
连接可以由任一方或双方发起,一旦连接建立,数据就可以双向对等地流动,而没有所谓的主从关系。三次握手是连接两端正确同步的充分必要条件,因为 TCP 建立在不可靠的分组传输服务至上,报文可能丢失、延迟、重复和乱序,因此,协议必须使用超时和重传机制。如果重传的连接请求和原先的连接请求在连接正在建立时到达,或者当一个连接已经建立、使用和结束之后,某个延时的连接请求才到达,就会出现问题。采用三次握手协议可以解决上述问题。如客户端发送的 ACK 数据段就是为了避免因网络延迟而导致的重复连接,因为这时客户端通过检查 ACK 数据段中的确认号就可得知该连接请求是否已失效。
双方同时主动连接的TCP连接建立过程
正常情况下,传输连接都是一方主动发起的,但也有可能双方同时主动发起连接,此时就会发生连接碰撞,最终只有一个连接能够建立起来。所有连接都是由它们的端点进行标识的,如果第一个连接请求建立起一个由套接字(x, y)标识的连接,而第二个连接也建立了这样一个连接,那么在TCP实体内部只有一个套接字表项。
当出现同时发出连接请求时,两端几乎同时发出一个 SYN 字段置1的数据段,并进入 SYN_SEND 状态。当每一端收到 SYN 数据段时,状态变为 SYN_RCVD, 同时它们都再发送 SYN 字段置1、ACK 字段置1的数据段,对收到的 SYN 数据段进行确认。当双方都收到对方的 SYN+ACK 数据段后,便都进入到了 ESTABLISHED 状态。下图显示了这种同时建立起连接过程,但最终建立的是一个TCP连接,不是两个,这点要注意。
同时发起连接的TCP连接建立过程
从上图看出,一个双方同时打开的传输连接需要交换4个数据段,比正常的传输连接建立所进行的三次握手多交换一个数据段。此外,要注意的是,此时没有将任何一端称为客户端或服务器,因为每一端即是客户端也是服务器。