TCP三次握手和四次挥手的流程?为什么TCP建立连接是三次握手而非两次或四次?

为什么TCP是三次握手而不是两次或者四次,个人觉得关于握手次数问题可以从通信的可靠性资源浪费,还有本质性的初始序列号去解释,但是资源的浪费并未涉及到问题的本质,所以资源方面只是弱相关的论据,可以借此由浅入深。

TCP建立连接和断开连接

首先解释一下TCP建立连接和断开连接的过程。
在这里插入图片描述

三次握手

1.Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

2.Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

3.Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间就可以开始传输数据了。

四次挥手

由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

1.数据传输结束后,客户端的应用进程发出连接释放报文段,并停止发送数据,客户端进入FIN_WAIT_1状态,此时客户端依然可以接收服务器发送来的数据。

2.服务器接收到FIN后,发送一个ACK给客户端,确认序号为收到的序号+1,服务器进入CLOSE_WAIT状态。客户端收到后进入FIN_WAIT_2状态。

3.当服务器没有数据要发送时,服务器发送一个FIN报文,此时服务器进入LAST_ACK状态,等待客户端的确认。

4.客户端收到服务器的FIN报文后,给服务器发送一个ACK报文,确认序列号为收到的序号+1。此时客户端进入TIME_WAIT状态,等待2MSL(MSL:报文段最大生存时间),然后关闭连接。

为什么是三次握手?

一.资源浪费观点

引自《计算机网络》释疑与习题解答 谢希仁

如果只有两次握手,那么当客户端的SYN连接请求在网络中阻塞,导致客户端没有接收到ACK报文,就会重新发送SYN,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的ACK确认信号,所以每收到一个SYN就只能主动建立一个连接,这会造成什么情况呢?如果客户端的SYN阻塞了,重复发送多次SYN报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
即两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求SYN报文,而造成重复分配资源。

二.可靠性论断

如果想确定双通道通畅,必须使用三个包的发送接收,也就是三次握手。这个问题的本质是:信道不可靠,但是通信双发需要就某个问题达成一致。而要解决这个问题,无论你在消息中包含什么信息,三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足在不可靠信道上可靠地传输信息这一需求所导致的。请注意这里的本质需求,信道不可靠,数据传输要可靠。三次达到了,那后面你想接着握手也好,发数据也好,跟进行可靠信息传输的需求就没关系了。因此,如果信道是可靠的,即无论什么时候发出消息,对方一定能收到,或者你不关心是否要保证对方收到你的消息,那就能像UDP那样直接发送消息就可以了。
三次是保证双方互相明确对方能收能发的最低值。理论上讲不论握手多少次都不能确认一条信道是“可靠”的,但通过3次握手可以至少确认它是“可用”的,再往上加握手次数不过是提高“它是可用的”这个结论的可信程度。另外TCP的可靠传输更多的是靠重传机制来保证的。

三、初始序列号

三次握手的本质是为了同步双方的初始序列号
为了实现可靠数据传输,TCP 协议的通信双方,都必须维护一个序列号, 以标识发送出去的数据包中,哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手,至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。TCP建立连接的握手,实质上就是建立一个双向的可靠通信连接,一边一个来回,每一边都自带超时重传来确保可靠性(而不是靠握手的次数)。TCP的3次握手是优化的结果,其实它应该是4次握手,由于是从零开始的建立连接,因此将SYN的ACK以及被动打开的SYN合并成了一个SYN-ACK(也就是第二次握手)。
握手的作用,旨在确定两个双向的初始序列号,TCP用序列号来编址传输的字节,由于是两个方向的连接,所以需要两个序列号。

如果连接不存在的IP或者某个确实存在的IP下没有监听的端口?

连接一个 IP 不存在的主机时,握手过程是怎样的?这篇文章讲的很好,包括抓包在内的分析过程这里就不再赘述,只说下结论:
1.IP不存在
1.1 在同一局域网内
第一次握手会失败(收不到ACK),接着不断尝试重发握手的SYN请求。同时,本机会不断发出ARP广播,企图获得目的机器的 MAC 地址,握手失败的原因就在于ARP广播无法得到ARP应答。
1.2 公网IP
与1.1不同,因为不在同一局域网,所以SYN请求会先发给局域网的默认网关(比如在家里面就是家用路由器),默认网关将请求路由到目的IP所在局域网的网关,网关ARP广播无法得到ARP应答,导致会不断重试SYN请求。这里与1.1不同的地方在于,1.1中用wireshark抓不到SYN握手包,只能抓到ARP广播包,而1.2中则都可以抓到,原因在于抓包是在数据链路层后进行的,可以理解为1.1里面,数据包根本就没出发送端主机。
2.IP存在端口不存在
2.1 回环地址127.0.0.1
因为IP存在,所以一直到网络层都是正确没问题的,只有到传输层才会区分端口,然后发现端口不存在,返回RST包,这时会断开连接,不会触发SYN重传了。当然这个过程都是在本机发生的。
2.2 局域网内
不同于2.1的是,是目的主机返回RST。
2.3 公网
2.3.1 自己的云服务器
目的主机返回RST,和局域网没本质区别。
2.3.2 baidu
这里只是举了个有安全策略的主机的例子,有防火墙策略,只开指定端口,其余端口不开放,SYN请求包到防火墙就被丢掉了,根本到不了目的主机,所以也不可能返回RST包。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值