TCP三次握手

TCP三次握手

上一篇文章已经说了TCP是面向连接的,那么TCP是如何建立连接的那?答案就是三次握手,如果你已经了解了TCP的三次握手,在面试的时候一定被问过为什么是三次握手?两次或者四次可以吗?带着这些问题,接下来我们使用wireshak抓包工具,看看TCP是如何进行三次握手的。

首先我们使用Java的Socket或者使用nc -l port监听一个端口号。例如:

然后我们再使用nc ip port建立连接并发送一些数据。lsof查看下连接状态已经是ESTABLISHED。

接下来我们用wireshark看下抓的包数据。

上图中1、2、3号包就是三次握手的数据包,[xxx]表示TCP数据段标志位,例如1号包是[SYN],3号包是[ACK]。关于标志位在上篇文章里已经讨论过了,这里就不详细展开了。

1. 三次握手的过程

image

不知道大家是否看明白了三次握手的过程,大家可以自己参照我画的三次握手的时序图仔细理解下,里面的TCP状态机,Win,Mss我会在后面给大家分析请暂时不要捉急,先搞清楚三次握手的流程就可以了。

1.1 介绍几个概念

  • Seq: Seq表示该报文段的序列号,TCP的每个报文段的序列号在正常传输下都是递增的,在三次握手中的客户端和服务端的第一个Sep称为ISN(初始序列号),因为TCP是全双工的,所以双方都需要一个ISN。我们不需要知道序列号是如何生成的,但是我们需要知道它是怎么增加的,因为在TCP的数据传输中收到乱序的数据包是根据序列号重新排序的。

为什么这里的ISN(初始序列号)为0,因为我们要频繁的对Seq进行计算,在wireshark中提供了Relative sequence number的相对序列号方式,简化我们的计算。

  • Len:表示数据包的长度,但是不包含TCP头的长度,三次握手中的数据。
  • ACK:表示确认收到了ACK号之前的数据包,如果对方没有发送数据包那么确认号保持不变,例如,A发送给B的数据包的Seq=x,Len=y那么B的回复的Ack号就是x+y。

1.2 序列号的增长方式

下个数据包的Seq=上个数据包的Seq + 上个数据包的Len,就是这么Easy。

⚠️三次握手中的ACK和Seq增长方式有所不同。

1.3 两个问题

  1. 三次握手可以是两次吗

答案:可以,但是不够可靠。因为网络上有多条传输路径,当客户端用于建立连接的第一个包跑到了一个延迟比较高的路径上,服务端迟迟没有响应,那么客户端会认为这个包丢而进行重发。然后第二个包很快建立了连接,并发送数据后关闭。这时候第一个包姗姗来迟,由于服务端不能识别这是一个旧的并且无效的连接(和序列号的生成又关闭,因为它不能无限的增加),就会响应这个请求。如果是三次握手,客户端收到这个ACK,就会发送一个RST包,释放这个连接,如果是两次就会建立一个无效的连接。

  1. 三次握手可以是四次吗

答案:可以,但是没必要。因为服务端的ACK不携带任何数据,一般会立即响应,多加一次ACK浪费流量。

参考阅读

  • TCP 为什么三次握手而不是两次握手(正解版)

  • 《Wiresharkwa网络分析就是这么简单》

关注作者公众号:

你可能感兴趣的:(TCP/IP)