TCP连接的建立

前言:TCP的问题已然困惑我很久了,一直是一知半解,靠记忆来记住TCP连接的过程,不能根本上理解,漏洞百出,最近抽时间把TCP经典书籍——《 TCP-IP详解》阅读了一下。废话不多说,这篇博客的目的是希望能帮助刚入门的老铁们以及和我一样一直只是知道大概的老铁们~

1、TCP连接的建立过程

先来放两张大家都熟悉的图:

TCP连接的建立_第1张图片

TCP连接的建立_第2张图片

上图和下图对应着看。上图是TCP连接建立的宏观过程:

1) 请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初
始序号(ISN
,在这个例子中为1415531521)。这个SYN段为报文段1。此时客户端发送位码为syn=1,

server端知由syn=1知道,client端要求联机。

2) 服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认
序号设置为客户的
ISN1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。(syn=1, ack=1)
3) 客户必须将确认序号设置为服务器的ISN1以对服务器的SYN报文段进行确认(报文
3)。
这三个报文段完成连接的建立。这个过程也称为三次握手(
three-way handshake 。

前两次握手过程很好理解,重要的是第三次握手,看似多余其实不然。这主要是为了防止已失效的请求报文段突然又传送到了服务器端而产生连接的错误。如果没有这第三次连接,会出现如下问题:

比如:客户端发送了一个连接请求报文段A到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文段B该服务端,而后 正常建立连接,数据传输完毕,并释放了连接(注意此间报文段A一直处于滞留状态)。但是请求报文段A延迟了一段时间后,又到了服务端,这本是一个早已失效的报文段,但是服务端收到后会误以为客户端又发出了一次连接请求,于是向客户端发出确认报文段,并同意建立连接。那么问题来了,假如这里没有三次握手,这时服务端只要发送了确认,新的连接就建立了,但由于客户端没有发出建立连接的请求,因此不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的连接已经建立了,并在 一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端判定为出了问题,才会关闭这个连接。这样就浪费了很多服务 器的资源。而如果采用三次握手,客户端就不会向服务端发出确认,服务端由于收不到确认,就知道客户端没有要求建立连接,从而不建立该连接。

现在来重点讨论下这第三次握手,假如TCP连接第三次握手包丢失了,TCP会作何应对呢?

· 当Client端收到Server的SYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;

· 如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。
· Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5。
· 如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。
· 但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。

这就是RST包的的重要意义。(后面再继续更新RST包相关知识,就不放在一篇中去讲,不然显得太长~)

这样三次握手正确进行,就能建立起一个TCP连接,就可以传输数据了。


2、TCP的可靠性

在网络分析中,读懂TCP序列号和确认号可以帮助我们理解TCP协议以及排查问题。
SYN:同步标志    同步序列编号(Synchronize Sequence Numbers)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把 TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。
ACK:确认标志    确认编号(Acknowledgement Number)栏有效。大多数情况下该标志位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据。
TCP协议工作在传输层,是一种可靠的面向连接的数据流协议。TCP之所以可靠是因为它保证了传送数据包的顺序,顺序是用一个 序列号来保证的。TCP通过数据分段中的序列号来保证所有传输的数据可以按照正常的顺序进行重组,从而保证数据传输的完整。

在TCP连接、数据传输、关闭三个过程中,每个过程完成不同的工作,而且序列号和确认号在每个过程中的变化都是不同的。

在TCP建立的过程中:

 1. 客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值,确认号是0; 

 2. 服务器收到这个同步请求数据包后,会对客户端进行一个同步确认。这个数据包中,序列号(ISN)是服务器随机产生的一个值,确认号是客户端的初始序列号+1;

 3. 客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值,确认号是服务器的初始序列号+1。




你可能感兴趣的:(网络)