浅谈 TCP 协议
您目前处于:技术核心竞争力  2016-08-05

一、TCP/IP

TCP 工作在网络 OSI 的七层模型中的第四层 —— Transport层,IP 在第三层 —— Network 层,ARP 在第二层 —— Data Link 层;在第二层上的数据,我们把它叫 Frame,在第三层上的数据叫 Packet,第四层的数据叫 Segment。 

TCP 是一个协议,那这个协议是如何定义的,它的数据格式是什么样子的呢?

下面就将每个字段的信息都详细的说明:

- Source Port 和 Destination Port:分别占用16位,表示源端口号和目的端口号;用于区别主机中的不同进程,而 IP 地址是用来区分不同的主机的,源端口号和目的端口号配合上 IP 首部中的源 IP 地址和目的 IP 地址就能唯一的确定一个 TCP 连接。

- Sequence Number:用来标识从 TCP 发端向 TCP 收端发送的数据字节流,它表示在这个报文段中的的第一个数据字节在数据流中的序号;主要用来解决网络报乱序的问题。

- Acknowledgment Number:32位确认序列号包含发送确认的一端所期望收到的下一个序号,因此,确认序号应当是上次已成功收到数据字节序号加1。不过,只有当标志位中的ACK标志为1时该确认序列号的字段才有效。主要用来解决不丢包的问题。

- Offset:给出首部中32 bit 字的数目,需要这个值是因为任选字段的长度是可变的。这个字段占4bit(最多能表示15个32bit的的字,即4*15=60个字节的首部长度),因此 TCP 最多有60字节的首部。然而,没有任选字段,正常的长度是20字节。

- TCP Flags:TCP 首部中有6个标志比特,它们中的多个可同时被设置为1,主要是用于操控 TCP 的状态机的,依次为 URG,ACK,PSH,RST,SYN,FIN。每个标志位的意思如下:

(1) URG:此标志表示 TCP 包的紧急指针域有效,用来保证 TCP 连接不被中断,并且督促中间层设备要尽快处理这些数据;

(2) ACK:此标志表示应答域有效,就是说前面所说的 TCP 应答号将会包含在 TCP 数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0;

(3) PSH:这个标志位表示 Push 操作。所谓 Push 操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队;

(4) RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;

(5) SYN:表示同步序号,用来建立连接。SYN 标志位和 ACK 标志位搭配使用,当连接请求的时候,SYN=1,ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有 SYN 的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这种扫描方式只是进行 TCP 三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行 TCP 的三次握手;

(6) FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送 FIN 标志位的 TCP 数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。

- Window:窗口大小,也就是有名的滑动窗口,用来进行流量控制。

二、三次握手

TCP 是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,连接是通过三次握手进行初始化的。三次握手的目的是同步连接双方的序列号和确认号并交换 TCP 窗口大小信息。

第一次握手:建立连接。客户端发送连接请求报文段,将 SYN 位置为1,Sequence Number 为 x;然后,客户端进入 SYN_SEND 状态,等待服务器的确认;

第二次握手:服务器收到 SYN 报文段。服务器收到客户端的 SYN 报文段,需要对这个 SYN 报文段进行确认,设置 Acknowledgment Number 为 x+1 (Sequence Number+1);同时,自己还要发送 SYN 请求信息,将 SYN 位置为1,Sequence Number 为 y;服务器端将上述所有信息放到一个报文段(即 SYN+ACK 报文段)中,一并发送给客户端,此时服务器进入 SYN_RECV 状态;

第三次握手:客户端收到服务器的 SYN+ACK 报文段。然后将 Acknowledgment Number 设置为 y+1,向服务器发送 ACK 报文段,这个报文段发送完毕以后,客户端和服务器端都进入 ESTABLISHED 状态,完成 TCP 三次握手。

Wireshark 抓包

三、四次分手

当客户端和服务器通过三次握手建立了 TCP 连接以后,当数据传送完毕,肯定是要断开 TCP 连接的啊。那对于 TCP 的断开连接,这里就有了神秘的"四次分手"。

第一次分手:主机1(可以是客户端,也可以是服务器端),设置 Sequence Number 和 Acknowledgment Number,向主机2发送一个 FIN 报文段;此时,主机1进入 FIN_WAIT_1 状态;这表示主机1没有数据要发送给主机2了;

第二次分手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number 为 Sequence Number 加1;主机1进入 FIN_WAIT_2 状态;主机2告诉主机1,我"同意"你的关闭请求;

第三次分手:主机2向主机1发送 FIN 报文段,请求关闭连接,同时主机2进入 LAST_ACK 状态;

第四次分手:主机1收到主机2发送的 FIN 报文段,向主机2发送 ACK 报文段,然后主机1进入 TIME_WAIT 状态;主机2收到主机1的 ACK 报文段以后,就关闭连接;此时,主机1等待 2MSL 后依然没有收到回复,则证明 Server 端已正常关闭,那好,主机1也可以关闭连接了。

四、为什么要三次握手

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

五、为什么要四次分手

TCP 是全双工模式,这就意味着,当主机1发出 FIN 报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回 ACK 报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了 FIN 报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次 TCP 连接。


转载请并标注: “本文转载自 linkedkeeper.com ”  ©著作权归作者所有