网络基础--TCP连接:三次握手、四次挥手

预备知识:

1. TCP连接的11种状态(指的是建立TCP连接时客户端、服务端(例如80端口)的端口的状态,):这个还有待学习补充

2. TCP报文格式:这个请参考:https://www.cnblogs.com/limanjihe/p/10134385.html

三次握手:

第一次握手:客户端向服务端发送一段TCP报文:

a. 标志位SYN=1,表示“请求建立新连接”

b. 序号seq=x(x是随机值,一般为1)

c. 将该数据包发送给server,client进入SYN_SENT状态,等待server确认

第二次握手:server端接收到报文后,通过标志位SYN=1知道client请求建立连接,返回一段TCP报文:

a.标志位SYN=1,server同意创建新连接

b.标志位ACK=1,表示此报文的确认序号(Ack序号)有效

c.序号seq=y(y是随机值)

d.确认序号(Ack序号)Ack=Seq + 1(这里的seq是第一次握手client发送的seq)

e.将数据包发送给client,server进入SYN_RCVD状态

第三次握手:client接收到server的确认收到数据的TCP报文后,检查ack是否为x+1,标志位ACK是否为1。如果正确,知道了从client到server的数据传输是正常的。发送第三段TCP报文:

a.标志位ACK=1,表示此报文的确认序号(Ack序号)有效

b.序号seq=x+1,这里的x是client第一次发送的seq值

c.确认序号Ack=Seq+1,即ack=y+1(这里的seq是第二次握手server发送的seq)

d.client进入ESTABLISHED状态

e.server检查标志位ACK是否为1,确认序号Ack是否为y+1。如果正确,则连接建立成功,server进入ESTABLISHED状态。可以互传数据了

为什么需要第三次握手?

强烈推荐看这个,一下子就明白了:https://blog.csdn.net/lengxiao1993/article/details/82771768

我把最重要的部分写下来:

1.网上搜出来的答案基本是:防止已失效的连接请求又传送到服务器端,因而产生错误。

2.不幸的是,这种解释是不准确的,TCP 采用三次握手的原因其实非常简单,远没有大部分博客所描述的那样云山雾绕。

为了实现可靠数据传输,TCP 协议的通信双方,都必须维护一个序列号,以标识发送出去的数据包中,哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。

如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认。

SYN攻击(这个以后会专门再写一篇):

一种DDOS攻击(2000YAHOO网站遭受的攻击,有些网络蠕虫病毒配合SYN攻击造成更大的破坏

SYNSYNchronize):同步序列编号(Synchronize Sequence Numbers)。是TCP/IP建立连接时使用的握手信号。

四次挥手

 

所谓的四次挥手即TCP连接的释放(解除)。连接的释放必须是一方主动释放,另一方被动释放。挥手之前主动释放连接的客户端结束ESTABLISHED阶段。随后开始四次挥手

第一次:

客户端想要释放连接,向服务端发送一段TCP报文:

a.标志位FIN=1,

b.序号seq=u(u是前面已经传送过来数据的最后一个字节的序号+1)

c.客户端进入FIN_WAIT_1 (终止等待1)状态,即半关闭阶段。并且停止client向server发送数据(这里停止的是正常连接时传输的数据,即非确认报文,而不是一切数据,所以客户端仍然能发送ACK确认报文),但是client仍然能够接收server传输过来的数据。

d.TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

第二次:

服务器端接收到client端的报文,确认客户端向关闭连接,服务端结束ESTABLISHED阶段,进入CLOSE_WAIT阶段(关闭等待),并返回一段TCP报文:

a.标志位ACK=1,表示此报文的确认序号(Ack序号)有效

b.确认序号ack=u+1

c.序号seq=v

d.服务器进入CLOSE_WAIT(关闭等待)状态。TCP服务器通知高层的应用进程。随后服务器准备释放服务器端到客户端方向上的连接。

e. 客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了自己发出的释放连接请求,于是关闭客户端到服务器端方向上的连接,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2(终止等待2)阶段客户端向服务器方向就释放了。此时客户端已经没有数据要发送了。但是服务器发送数据,client依然能接收。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

 

第三次:

服务器将最后的数据发送完毕后。服务器端自从发出ACK确认报文之后,经过CLOSE_WAIT阶段,做好了释放服务器端到客户端方向上连接的准备,再次向客户端发出一段TCP报文(连接释放报文):

a.标记为FIN=1,

b.标记为ACK=1, 表示此报文的确认序号(Ack序号)有效

c.序号seq=w(假定此时的序列号为w)

d.确认序号Ack=u+1(与上次ACK确认报文相同)

e.服务器进入LAST_ACK(最后确认)状态,等待客户端确认

第四次:

客户端收到服务器的连接释放报文后,必须发出确认:

a.标志位ACK=1

b.确认序号ack=w+1

c.序号是seq=u+1

d.服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

e.客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2*MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

双方四次挥手过程中传输的TCP报文,确认序号Ack和序号seq的值,保证了TCP报文传输的连贯性。

为什么需要四次挥手?

因为服务器是被动关闭。收到客户端释放连接的请求时,还有必要的数据需要处理,并不能立即释放连接。所以服务器先返回ACK确认报文,经过CLOSE_WAIT阶段准备好释放连接之后,再返回FIN报文。

为什么客户端在TIME_WAIT阶段要等待2MSL?

为了确认服务端能够收到客户端发出的最后的ACK确认报文。

client在发送完最后的ACK确认报文后,该ACK可能丢失。Client必须确认server接收到了该ACK,才能关闭连接,所以在进入到TIME_WAIT状态后,client会设置一个时长2MSL的计时器。如果在2MSL内再次受到FIN,说明服务端没有收到client的ACK确认报文。客户端再次向服务端发出ACK确认报文,计时器重置,重新开始2MSL的计时。

如果client在2MSL内没有再次受到服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段。完成四次挥手。

MSL:Maximum Segment Lifetime,一段TCP报文在网络中最大的存活时间。

TIME_WAIT阶段,等待的时间为什么是2个MSL?(这个地方没明白)

2MSL,就是一个发送和一个回复所需的最大时间。

这里有一点说不通,client怎么就能确定,如果server没有收到ACK报文,在这2MSL内,client就能收到服务端发送的FIN报文?服务器端发送FIN报文的时间机制?

这里有一个问题没有解释清楚,就是服务器端判断client的ACK确认包传过来的时限是多长(个人猜测,也是2MSL)?,并依据此时限再次发送FIN包?

已经建立了TCP连接,但是客户端突然出故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

 

欢迎大家批评指正!!!(^_−)☆ (*^▽^*)

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值