前言:TCP的问题已然困惑我很久了,一直是一知半解,靠记忆来记住TCP连接的过程,不能根本上理解,漏洞百出,最近抽时间把TCP经典书籍——《 TCP-IP详解》阅读了一下。废话不多说,这篇博客的目的是希望能帮助刚入门的老铁们以及和我一样一直只是知道大概的老铁们~
1、TCP连接的建立过程
先来放两张大家都熟悉的图:
上图和下图对应着看。上图是TCP连接建立的宏观过程:
1) 请求端(通常称为客户)发送一个SYN段指明客户打算连接的服务器的端口,以及初
始序号(ISN,在这个例子中为1415531521)。这个SYN段为报文段1。此时客户端发送位码为syn=1,
server端知由syn=1知道,client端要求联机。
2) 服务器发回包含服务器的初始序号的SYN报文段(报文段2)作为应答。同时,将确认
序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。(syn=1, ack=1)
3) 客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认(报文
段3)。
这三个报文段完成连接的建立。这个过程也称为三次握手(three-way handshake) 。
前两次握手过程很好理解,重要的是第三次握手,看似多余其实不然。这主要是为了防止已失效的请求报文段突然又传送到了服务器端而产生连接的错误。如果没有这第三次连接,会出现如下问题:
比如:客户端发送了一个连接请求报文段A到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文段B该服务端,而后 正常建立连接,数据传输完毕,并释放了连接(注意此间报文段A一直处于滞留状态)。但是请求报文段A延迟了一段时间后,又到了服务端,这本是一个早已失效的报文段,但是服务端收到后会误以为客户端又发出了一次连接请求,于是向客户端发出确认报文段,并同意建立连接。那么问题来了,假如这里没有三次握手,这时服务端只要发送了确认,新的连接就建立了,但由于客户端没有发出建立连接的请求,因此不会理会服务端的确认,也不会向服务端发送数据,而服务端却认为新的连接已经建立了,并在 一直等待客户端发送数据,这样服务端就会一直等待下去,直到超出保活计数器的设定值,而将客户端判定为出了问题,才会关闭这个连接。这样就浪费了很多服务 器的资源。而如果采用三次握手,客户端就不会向服务端发出确认,服务端由于收不到确认,就知道客户端没有要求建立连接,从而不建立该连接。
现在来重点讨论下这第三次握手,假如TCP连接第三次握手包丢失了,TCP会作何应对呢?
· 当Client端收到Server的SYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;
这就是RST包的的重要意义。(后面再继续更新RST包相关知识,就不放在一篇中去讲,不然显得太长~)
这样三次握手正确进行,就能建立起一个TCP连接,就可以传输数据了。
2、TCP的可靠性
在TCP连接、数据传输、关闭三个过程中,每个过程完成不同的工作,而且序列号和确认号在每个过程中的变化都是不同的。
在TCP建立的过程中:
1. 客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值,确认号是0;
2. 服务器收到这个同步请求数据包后,会对客户端进行一个同步确认。这个数据包中,序列号(ISN)是服务器随机产生的一个值,确认号是客户端的初始序列号+1;
3. 客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值,确认号是服务器的初始序列号+1。