tcp三次握手_对TCP三次握手的理解

写一写我自己对TCP三次握手的理解,希望可以帮助到部分同学对这个知识点的记忆.

先放一个到处都可以见到的图:

0ce5dd2491aa3a1e6ecb3727203e2cd5.png
TCP三次握手

以前我看到TCP三次握手,再一看这个图片觉得好复杂,就懒得再看了.感觉可能是被握手这个词误导了,觉得握手是一个双方的行为,那握手三次,岂不是有六次传输信息嘛!其实仔细看看并没有那么复杂,更加类似于抛绣球,我抛给你,你抛给我,我再抛给你,一共也就抛了三次而已.

TCP协议中,主动发起请求的一端称为客户端(以下叫A),被动接收请求的一端称为服务端(以下叫B),TCP提供全双工通信,所以不管是客户端还是服务端,建立连接以后都可以发送和接收数据.

一开始,双方都是CLOSED状态(可以对应上图来看),准备通信时,双方都要创建自己的传输控制块(TCB),服务器端在创建完传输控制块后就进入了LISTEN状态,等着客户端发送请求过来.

第一次握手:

客户端向服务端发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端便进入SYN-SENT状态。

SYN=1,SYN即是synchronous,同步的意思,大概表示我想要和你同步,也就是建立连接.

ACK=0,ACK即是acknowledgement,确认的意思,这里是由客户端主动发出的连接请求,这是第一次发出消息,自然不会是确认服务器发送过来的消息.所以传送ACK=0.和上面的SYN=1在一起,就表示这个是连接请求报文.

seq=x,seq即是Sequence,就是一个顺序的序号,这里x就是本次TCP通信(由客户端作为发送方时)字节流的初始序号.

SYN-SENT状态,很好理解了,就是表示我已经发送了同步的请求.

第二次握手:

服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。该应答发送完成后便进入SYN-RCVD状态。

SYN=1,和上面一样,表示服务器端也想和客户端同步,或者说表示当前这个请求依然是表示再建立连接.

ACK=1,表示确认客户端发来的连接请求,和上面的SYN=1一起,就表示这个是连接同意的应答报文.

seq=y,这里y就是本次TCP通信(由服务端作为发送方时)字节流的初始序号(是的我复制了上面那句).

ack=x+1,ack表示我收到你发过来的报文中seq=x(第一次握手的时候),我希望你下一个数据报 发送 序号从x+1开始的 字节(有点绕,所以我加了一个空格来断句).

SYN-RCVD状态,表示我接收到了同步的请求.

第三次握手:

当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示:服务端发来的连接同意应答已经成功收到。 该报文段的头部为:ACK=1,seq=x+1,ack=y+1。 客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接就建立了.

第三次握手的时候,已经没有了SYN,客户端发送的seq对应,服务器端发送过来的ack,反过来也一样,只要明白客户端和服务器端是分别计数的就好理解了.

这里还有一个常见的问题是,为什么不能客户端发送请求,服务器接收到后发送确认就直接建立连接呢,也即是两次握手,而非要三次呢?

这是因为在网络不通畅的时候,客户端发送的连接请求(第一次握手)可能一直到不了服务端那里,客户端等待服务器端的响应超时以后,客户端是会重新发出连接请求的,那么之前那次请求也就失效了.假设后一次服务器正确接收到了请求,双方建立通信,通信完毕后关闭了连接,这时那个之前发出的失效连接抵达了服务端,如果服务器收到请求就直接进入ESTABLISHED状态,等到客户端发送信息,但是客户端其实早就CLOSED了.服务端将会一直等待下去,这样浪费服务端连接资源.

其实相对于这篇内容,网上表述更加专业的文章有很多,以上只是我加入了一些自己的理解来尝试解释一下TCP的三次握手,希望可以帮助一些同学更加形象的理解三次握手是在干嘛.当然了,在面对面试官的时候,还是不要说什么抛绣球这类话了,这样显得很业余,还是要用更专业的词汇来回答,这些不太准确的表述,只是为了方便大家记忆.


以下内容纯属扯淡:

A在收到B的连接同意的应答(第二次握手)之后,由于B不确A是否已经收到了,所以A还要向B发送一次确认报文(第三次握手),表示我收到了你的连接同意应答.

但是实际上,即使如此,A也不能确定B是否收到了他发送的确认报文(是否收到了第三次握手的消息),所以B应该回给A一个确认报文,表示确认我收到你发送的关于确认收到了我发送给你的连接同意应答的报文(第四次握手).

但是这样就行了吗?

当然不是.这时B又无法确认A是否收到了他刚刚发送的关于表示确认我收到你发送的关于确认收到了我发送给你的连接同意应答的报文了.所以只有再发送一次关于.................的报文(第五次握手).

(第六次握手)

(第七次握手)

(第八次握手)

........

这时候你会问了,这不是没完没了了吗?

对,这其实就是进入了众所周知的"TCP黑暗森林",只要哪边停下来,那么对方便无法确认是否已经收到了报文,就会面临一直等待而宕机的风险.所以最好的处理方式是不要发送任何请求,如果收到了其他地方发来的请求,一定不要回复,不要回复,不要回复!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值