天天看点

TCP三次握手,四次挥手3次握手过程详解(建立连接)4次挥手过程详解(关闭连接)最后一个问题:为什么建立连接是三次握手,而关闭连接却是四次挥手呢? 

通俗、简单的讲一下TCP的连接过程。

首先TCP是一种面向连接的,稳定可靠安全的一种传输字节流的方式。

根据书本,我先把TCP的报文格式给大家列一下。

主要就是一些 seq随机序号,用来产生随机值方便校验。SYN发起建立连接标志位。FIN发起关闭连接标志物。RST发起重新连接的标志位。

ack=发起方的seq+1,用来校验。

具体看下面:

1 序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

2 确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=Seq+1。

3 标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:

       (A)URG:紧急指针(urgent pointer)有效。

       (B)ACK:确认序号有效。

       (C)PSH:接收方应该尽快将这个报文交给应用层。

       (D)RST:重置连接。

       (E)SYN:发起一个新连接。

       (F)FIN:释放一个连接。

需要注意的是:

(A)不要将确认序号Ack与标志位中的ACK搞混了。

(B)确认方ack=发起方seq+1,两端配对。 

3次握手过程详解(建立连接)

所谓三次握手即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务器进行三次通信。就像打电话:

A:喂,你好听到了吗? (第一次)                    (本次目的:发起请求)

B:我听到了,那你听的到我说话吗? (第二次)  (本次目的:服务器能够收到客户端的)

A:我也听到了 (第三次)                                (本次目的:客户端能够收到服务器的

图解:

TCP三次握手,四次挥手3次握手过程详解(建立连接)4次挥手过程详解(关闭连接)最后一个问题:为什么建立连接是三次握手,而关闭连接却是四次挥手呢? 

(1)第一次握手:

客户端将标志位SYN置为1,随机产生一个值seq=x,然后把数据包发给服务器,然后客户端进入SYN_SENT(建立连接发送状态)状态,等待服务器的回复。

(2)第二次握手:

服务器首先看到数据包的SYN=1,就知道这是要发起建立连接,然后服务器把SYN置为1,同时把ACK置为1(表示确认收到信息),然后产生一个随机值seq=y,然后把ack=客户端的seq即x+1,然后把数据包传给客服端,服务器就进入SYN_RCVD(建立连接收到状态)状态。

(3)第三次握手:

客户端收到数据包后,发现SYN和ACK都为1,表示这是建立连接的部分,然后也收到了我刚才发的数据包,然后对比检验服务器发的ack是不是等于=x+1,是的话校验成功。然后客户端也把ACK置为1,表示收到了服务器的序号。然后把ack=y+1发送给服务器,进入ESTABLISHED(建立状态),服务器和客户端完成三次握手,就可以开始传输数据了。

SYN攻击:

在三次握手过程中,服务器收到客户端的SYN请求连接后,需要发进入SYN_REVD状态(等待),SYN攻击就是客户端在短时间内伪造大量不存在的IP地址,并向服务器不断地发送SYN包,服务器回复确认包,并等待客户端的确认,由于源地址是不存在的,因此,服务器需要不断重发直至超时,数据量过大,从而引起网络堵塞甚至系统瘫痪。

检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了。

4次挥手过程详解(关闭连接)

三次握手耳熟能详,四次挥手估计就少有人知道了。所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

我们还是以打电话来说明:

A:那这次先聊到这里,我们挂了吧。                                      (第一次目的:客户端发起关闭FIN请求)

B:好,我知道了(表示回复客户端的关闭)。                          (第二次目的:服务器收到客户端关闭请求,并回复ACK=1)

B:那我们聊到这里,那我挂了?                                            (第三次目的:服务器向客户端FIN关闭请求)

A:好的,拜拜        (发一个ACK=1,服务器就关闭了)            (第四次目的:服务器收到ACK然后关闭,结束)         

还是先看图解:

TCP三次握手,四次挥手3次握手过程详解(建立连接)4次挥手过程详解(关闭连接)最后一个问题:为什么建立连接是三次握手,而关闭连接却是四次挥手呢? 

 具体流程看下面(下面会讲为什么是三次握手,为什么是四次挥手)

第一次挥手:

    Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

第二次挥手:

    Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

第三次挥手:

    Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

第四次挥手:

    Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

最后一个问题:

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

        这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。

        而关闭连接时,当收到对方的FIN报文时,仅仅表示客户端不再发送数据了但是可能还在接收数据,服务器也未必全部数据都发送给对方了,(服务器可能还在发数据)所以服务器可以立即close,也可以发完数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,服务器会把ACK和FIN一般都会分开发送。 先发ACK表示我收到你关闭请求了。然后会等自己发完以后,再去发送FIN请求。(而在建立连接的时候, ACK和SYN是一起发的。关闭的时候ACK先发,FIN后发,因为一般确保服务器数据发完了才会关闭)。

            通俗的说: 你总不能说关闭,我马上就关了吧,也要等我把话说完。多出的一步,就是服务器把ACK和FIN分开发了,等待把数据传完才发送FIN请求。

二:简单的说一下time_wait和close_wait

time_wait是在tcp四次挥手的时候,客户端主动发送关闭连接时候,最后一步的等待时间,通常是2MSL(也就是2倍的 数据包在网络传输的时间周期)

1.防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失)

2. 可靠的关闭TCP连接。在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。另外这么设计TIME_WAIT 会定时的回收资源,并不会占用很大资源的,除非短时间内接受大量请求或者受到攻击。

自己通俗解释:

1防止服务器可能会出现丢失的包,如果没有等待的话,这个丢失的包,可能会传给下一次新的连接。2MSL就是2倍的数据包在网络生存的最大时间。

2也防止客户端在发送最后一个ACK时,出现了丢失,如果有2倍的MSL time_wait 可以让他进行重新关闭,否则新来的连接会不成功,因为服务器处于 last_ack,会rst掉新的SYN连接

https://www.jianshu.com/p/44655bff60a4

close_wait是在tcp四次挥手的时候,当服务端收到客户端发来的FIN关闭请求,立即恢复了ACK确定数据包。从发送这个ACK包到服务端主动调用close()方法发送FIN请求时的时间,称为close_wait。主要是服务端受到FIN关闭的时候,服务端可能还有数据正在发送,不能够马上也关闭,需要等数据发送完成以后,才会主动发送FIN。所以会先发送ACK确定包,隔出一段时间才发送FIN数据包。

继续阅读