在TCP连接中,无论是客户端还是服务端,都有可能成为发送端或接收端,这是因为TCP是一个全双工协议,允许数据在同一连接中双向流动
- 客户端(Client) :通常是指主动发起连接请求的一方。例如,在Web浏览中,用户计算机上的浏览器软件(客户端)会主动向Web服务器(服务端)发送连接请求。
- 服务端(Service) :是指被动等待连接请求的一方。如上述例子中的Web服务器,它会在某个固定端口监听来自客户端的连接请求。
TCP通讯时讯 :
Wireshark抓包完整通讯:
下面我们先分析一下TCP是如何建立连接的。
一、专有名词解析
1.1 序列号(Seq)
在TCP(传输控制协议)中,序列号是一个32位的数值,用于唯一标识每个数据段中第一个字节的位置。当两个主机之间建立TCP连接时,它们会协商一个初始序列号,这个序列号随着每个数据段的发送而递增。序列号的主要作用在于确保数据包能够按照正确的顺序被接收方接收,即使在网络传输过程中出现了数据包的乱序或丢失,接收端也能够依据序列号将数据重新排列成原始的顺序。此外,序列号还与确认应答(ACKnowledgment)机制紧密相关,接收方通过发送带有特定确认号(即期望接收的下一个字节的序列号)的ACK包来告知发送方哪些数据已被成功接收。这种机制不仅支持数据的可靠传输,还帮助实现流量控制和连接的建立与终止过程。
1.2 窗口大小(Win)
在TCP(传输控制协议)中,窗口大小(Win)是一个重要的参数,位于TCP报头中,用于实现高效的流量控制。窗口大小是一个16位的字段,它代表接收端当前允许发送端连续发送而不必立即等待确认的最大字节数。这个机制的核心在于,接收端通过告知发送端其缓冲区中可用的空间大小,来控制发送端发送数据的速度。当接收端的缓冲区接近满载时,它可以减小窗口大小甚至将其设为零,指示发送端暂停发送数据,以防数据溢出。相反,当接收端有更大的缓冲区空间可用时,它可以增大窗口大小,允许发送端发送更多的数据。通过这种方式,窗口大小动态调整,确保了数据传输的平滑性和高效性,同时也避免了缓冲区溢出造成的潜在数据丢失问题。此外,窗口大小机制还有助于提高传输效率,因为它允许发送端连续发送多个数据段而不必为每个数据段单独等待确认,从而减少了不必要的等待时间和网络拥塞的可能性。
1.3 长度 Length 与 Len
Length
: 这是Wireshark中显示的整个TCP数据段的长度,包括TCP报头和数据部分。Len
: 这是TCP数据段中数据部分的长度,以字节为单位。
Length
的值反映了整个TCP数据段的大小,包括TCP报头和数据部分。在TCP通信的不同阶段,Length
的值会根据数据段中包含的数据量和TCP报头的长度(包括任何选项字段)而变化。
Len
的值反映了TCP数据段中实际的数据负载的大小,不包括TCP报头。在TCP通信的不同阶段,Len
的值会根据实际传输的数据量而变化。例如,在三次握手阶段,Len
的值为0,因为这些数据段中没有实际的数据负载;而在数据传输阶段,Len
的值会根据实际传输的数据量而变化。
二、TCP建立连接(三次握手)
- 客户端:192.168.0.2:5000
- 服务端:192.168.0.30:2021
2.1 第一次握手**(SYN)**
源地址:192.168.0.2 目的地址:192.168.0.30
TCP Port numbers reused] 5000 -> 2021 [SYN] Seq=0 Win=4096 Len=0 MSS=1460
解释:源地址192.168.0.2向目的地址192.168.0.30发送一个SYN包,请求建立连接。源端口是5000,目的端口是2021。序列号(Seq)为0,窗口大小(Win)为4096,最大段大小(MSS)为1460。
2.2 第二次握手**(SYN-ACK)**
源地址:192.168.0.30 目的地址:192.168.0.2
TCP 2021 -> 5000 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460
解释:目的地址192.168.0.30向源地址192.168.0.2发送一个SYN-ACK包,确认收到SYN包并同意建立连接。序列号(Seq)为0,确认号(Ack)为1,窗口大小(Win)为8192。
2.3 第三次握手**(ACK)**
源地址:192.168.0.2 目的地址:192.168.0.30
TCP 5000 -> 2021 [ACK] Seq=1 Ack=1 Win=4096 Len=0
解释:源地址192.168.0.2向目的地址192.168.0.30发送一个ACK包,确认收到SYN-ACK包,完成三次握手。序列号(Seq)为1,确认号(Ack)为1,窗口大小(Win)为4096。
2.4 综合分析
2.4.1 序列号(Seq):
- 在TCP三次握手的第一阶段,客户端向服务器发送一个SYN包,并附带一个初始序列号(Seq=0),这表示客户端希望从序列号0开始发送数据。
- 服务器接收到SYN包后,回应一个SYN-ACK包,其中包含了自己的初始序列号(Seq=0),并确认了客户端的序列号(Ack=1),表示它已接收到客户端的序列号0,并期待后续的数据从序列号1开始。
- 最后,客户端发送一个ACK包,确认号(Ack=1)表明客户端收到了服务器的序列号0,并准备接收从序列号1开始的数据。
2.4.2 窗口大小(Win):
- 在第一次握手中,客户端(源地址为192.168.0.2)发起了连接请求,发送了一个SYN包,并设置了窗口大小为4096(Win=4096)。这意味着客户端告诉服务器,它目前可以接收最多4096字节的数据。
- 第二次握手中,服务器(源地址为192.168.0.30)回应了一个SYN-ACK包,它的窗口大小为8192(Win=8192)。这表明服务器愿意接收客户端的数据,并且它的接收缓冲区当前可以容纳最多8192字节的数据。同时,这也意味着服务器向客户端表明它可以处理比客户端所提议的更大的数据量。
- 最后一次握手中,客户端发送了一个ACK包来确认收到了服务器的SYN-ACK,并且其窗口大小保持为4096(Win=4096)。这表明客户端再次确认它可以接收最多4096字节的数据,并且它准备好了接收后续的数据流。
通过三次握手过程中的窗口大小信息交换,客户端和服务器协商了彼此的接收能力,并且为后续的数据传输做好了准备。这些窗口大小的值反映了双方在连接建立初期的流量控制策略,确保了数据传输的平稳性和可靠性。在整个握手过程中,窗口大小的动态调整确保了数据传输的效率,同时也防止了由于一方接收能力不足而导致的数据溢出或丢失。
2.4.3 长度(Len)
- 在第一次握手中,客户端发起连接请求,发送了一个SYN包,并设置了序列号为0(Seq=0)。这意味着客户端希望从0开始发送数据。由于这是一个SYN包,它并没有携带任何应用层数据,因此
Len=0
,表明该数据段中没有实际的数据负载。 - 第二次握手中,服务器回应了一个SYN-ACK包,它的序列号也是0(Seq=0),表示服务器愿意从0开始接收数据,并确认收到了客户端的SYN包,期望接下来接收的序列号为1(Ack=1)。同样地,由于这是一个SYN-ACK包,它也没有携带任何应用层数据,所以
Len=0
,表示该数据段中也没有实际的数据负载。 - 最后一次握手中,客户端发送了一个ACK包来确认收到了服务器的SYN-ACK,并且确认号为1(Ack=1),表示客户端已经收到了服务器序列号为0的数据,准备接收序列号为1之后的数据。这个ACK包也没有携带任何应用层数据,因此
Len=0
,再次表明该数据段中没有实际的数据负载。
在TCP三次握手过程中,
Len
字段均为0,这是因为SYN、SYN-ACK和ACK数据段的主要功能是同步序列号、确认号以及连接参数,而不是传输用户数据。因此,在这三个阶段中,Len=0
表明这些数据段仅包含控制信息,而没有实际的数据负载。这样的设计使得TCP能够在正式的数据传输之前完成必要的连接建立和参数协商工作,确保后续的数据传输能够顺利进行。