TCP连接三次握手四次挥手

三次握手

  1. 刚开始,客户端处于close状态,服务器端处于listen状态
  2. 第一次握手:客户端向服务器端发送SYN(请求同步)报文,并加上自己的初始序列号(客户端id)ISN(c),告诉对方自己是谁,此时客户端处于SYN_Send状态(发送状态).
  3. 第二次握手:服务器接收到客户端的SYN报文后,会向客户端发送自己的SYN报文,并加上自己的初始序列号(服务器端id)ISN(s),同时会把客户端的ISN(c)+1作为ACK(应答检验)的值,表示已经收到客户端的SYN,此时服务器处于SYN_Rcvd状态(中间状态,再进一步接收到客户端的ACK就进入建立状态).
  4. 第三次握手:客户端收到报文后,将ACK值-1检查ISN(c),确认无误后,会将服务器端的ISN(s)+1作为ACK的值发送给服务器端,表示已经收到服务器端的SYN,此时客户端处于establised状态(建立状态).
  5. 服务器端收到ACK后,将ACK值-1检查ISN(s),确认无误后,也处于establised状态(建立状态),此时双方建立连接.

为什么需要三次握手才能确定连接,两次不行?

握手连接要确定的问题是双方的发送能力和接收能力,四项都正常才能建立连接

第一次握手:客户端发送,服务器端接收.客户端可以确认:客户端的发送;服务器端可以确认:客户端的发送,服务器端的接收

第二次握手:服务器端发送,客户端接收.客户端可以确认:客户端的发送,接收,服务器端的发送,接收;服务器端可以确认:客户端的发送,服务器端的接收,发送

 第三次握手:客户端发送,服务器端接收.客户端可以确认:客户端的发送,接收,服务器端的发送,接收;服务器端可以确认:客户端的发送,接收,服务器端的接收,发送

因此,需要三次才可以建立连接.

ISN是固定的吗?

如果ISN是固定的话,攻击者很容易猜出后续的确认号,因此ISN是动态生成的.

什么是半连接队列?

服务器在第一次接收客户端的SYN之后,就会处于SYN_RCVD状态.此时双方还没有完全建立起连接,这种状态下请求会被放在一个队列中,这个队列就是半连接队列,如果未收到客户端的回传,服务器端会进行重连,如果重连次数过多,会将请求从半连接队列中清除

举个简单一点的例子描述三次握手.甲乙两人在河的对岸,两人都想知道对方的信息然后开始交流,此时,甲先开始沟通

甲:你好(SYN),我是114(ISNc),能听到吗?(发送状态)

乙:你好(SYN),114(ACK),我是514(ISNs),能听到吗?(半连接状态)

甲:514(ACK),我听到了(建立状态)

经过这三次的沟通,甲乙两人就可以知道双方信息,并确定可以正常沟通了.

四次挥手

客户端和服务器端都可以主动发起断开连接请求,断开连接需要四次挥手,这里假设是客户端发起的断开请求.

第一次挥手:客户端向服务器端发送一份FIN(结束)包,客户端由establised(连接状态)变成结束等待1状态FIN-WAIT-1;

第二次挥手:服务器端接收到了FIN包,并会送一份ACK包,表示自己进入关闭等待状态CLOSE-WAIT,客户端进入结束等待2状态FIN-WAIT-2;服务端此时还可以发送未发送的数据,客户端此时还可以接收数据.

第三次挥手:待服务端发送完数据后,发送一份FIN包,进入最后确认状态LAST-ACK;

第四次挥手:客户端接收到服务器的报文后,会回送一份ACK包,进入超时等待状态TIME-WAIT,超时时间过后关闭连接CLOSED,而服务器端在接收完客户端传回的确认数据后立即关闭连接CLOSED

设置超时时间的原因?

假设客户端在发送完最后确认的ACK包后立即关闭连接,此时ACK在网络中丢失,服务器端将一直停留在LAST-ACK状态;如果客户端在发送完ACK包后等待一段时间,而服务器端没有收到,服务器端将会重新发送FIN包,客户端会响应新的FIN包,重发ACK包,并刷新超时时间.

 四次挥手的过程好比你在周末的时候想回家喝妈妈煲的鸡汤,于是你打电话给妈妈(应答过程大概就是这样)

你:妈妈,我这个周末想回家喝鸡汤(这时候,你进入等待妈妈的回复)

妈妈:好的,我看看家里还有没有老母鸡(妈妈开始检查家里的存货,而你继续等待妈妈的回复)

妈妈:家里还有一只老母鸡,你快点回来吧(妈妈开始煲鸡汤)

你:好的,我马上回来(然后你开始先等一会,万一家里有什么事了,妈妈会打电话再次告诉你,暂时这个鸡汤煲不了了,让你再定一个时间,如果妈妈没有再打电话回来,那你就立马收拾东西回家了)

在四次挥手中的双方序号和确认号变化(感觉这块不是很重要)

因为在发送http请求和响应时序号和确实号被不断递增,因此这里就不用固定数字表示序号和确认号了,假设是x和y

第一次挥手时,客户端发送自己的序号和确认号给服务器端(客户端序号和确认号分别为x,y)

第二次挥手时,服务器端将客户端的确认号作为自己的序号,客户端的序号+1作为自己的确认号(服务器端序号和确认号分别为y,x+1)

第三次挥手时,因为没有进行一来一回的相互通信,所以序号和确认号没有变化(服务器端序号和确认号分别为y,x+1)

第四次挥手时,客户端将服务器端的确认号作为自己的序号,服务器端的序号+1作为自己的确认号(客户端序号和确认号分别为x+1,y+1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值