TCP相关

一、三次握手

TCP:传输控制协议。面向连接的,可靠的。

在建立连接时,tcp协议采用经典的三次握手机制。

三次握手中TCP报文的seq,ack,SYN和ACK起到了关键性作用。Seq是报文中32位二进制的数据号,ack是32位的确认号(和ACK区分开)。SYN和ACK则都是1位的标志位。 

三次握手的具体实现过程:

1. 第一次握手:Client(客户端主机A)向Server(服务器主机B)发送一个连接请求,在这个包中,标志位SYN=1,发送序号seq=x。Client(客户端)进入SYN_SEND(已发送)状态,等待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(已建立)状态。

三次握手的目的:

三次握手的目的是要确认对方收到了自己的数据包,或者说双方都要确认彼此的收发能力正常这个目标就是通过“确认号(ack)”字段实现的。计算机会记录下自己发送的数据包序号Seq,待收到对方的数据包后,检测“确认号(ack)”字段,检查ack=seq+1是否成立。

个人理解:

在三次握手中,服务器和客户端各自发送了一个seq,并且收到了对应的ack = seq+1。从而确定了双方接收,发送的能力都没有问题。

第一次握手:服务器收到客户端数据包,服务器确服务器接收能力客户端发送能力正常

第二次握手:  客户端收到服务器数据包, 客户端确认服务器发送能力,接收能力客户端发送能力,接收能力正常。

第三次握手:服务器再次收到客户端数据包,服务器确认了服务器发送能力正常。

至此,双方都确认了彼此的收+发能力都正常,连接建立。

  • TCP的三次握手一定能保证传输可靠吗?
  • 不能
  • 三次握手比两次更可靠,但也不是完全可靠,而追加更多次握手也不能使连接更可靠了。因此选择了三次握手。比如:第三次握手时失败,此时客户端会认为连接正常,而此时服务器端连接尚未建立
  • 世界上不存在完全可靠的通信协议。从通信时间成本空间成本以及可靠度来讲,选择了“三次握手”作为点对点通信的一般规则。这是“两军通信”问题。

二、四次挥手

在TCP断开连接时,会发送四个数据包用于确认断开,称为四次挥手。

 四次挥手具体过程:

第一次挥手:当客户A要断开TCP连接时,发送一个包,其中标志位fin=1,ACK=1,发送序号seq=x,确认序号ack=y。Client进入FIN_WAIT_1状态(已发送fin,等待回复)。
第二次挥手:客户B知道A要断开后,发送一个确认包,其中标志位ACK=1发送序号,seq=y确认序号ack=x+1,Server进入CLOSE_WAIT状态(被动关闭)。
第三次挥手:客户B也断开TCP连接,此时发送一个包,其中,标志位fin=1,发送序号seq=y+1,Server进入LAST_ACK状态(确认请求)。
第四次挥手:客户A收到B的断开请求后,Client进入TIME_WAIT状态,接着发送一个确认包,标志位ACK=1,发送序号seq=x+1,确认序号ack=y+2;Server进入CLOSED状态(关闭)。

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

为什么关闭连接是四次挥手呢?

因为服务器收到FIN报文时,往往并不能直接关闭socket,因为可能有一些数据还没有发送完成。因此在四次挥手过程中,第二和第三次挥手是分两步进行。而在建立连接时,不需要考虑关闭问题,这两步可以合为一次握手。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

1.保证可靠关闭。如果在此时第四次握手没有成功,服务端则会继续发送FIN,而客户端会再次返回ACK,以确保服务端能够正确收到ACK并关闭。

2.保证所有的数据都已经发送。假设客户端在关闭之后又重新建立连接,TCP协议判断不同连接的依据是socket pair,而新连接的端口号又可能和老连接相同。此时如果有残存在网络中的数据,则会被认为是新连接的数据,产生混乱。

TCP可靠性的来源是什么?

1.ACK机制

如上文提到的,每次接收方收到消息后,都会回复一个ACK(回执)。而ACK是根据数据序号seq确定的。比如发送方发送的的seq=u,则接收方回复的ACK=u+1。由此,可以对多种情况进行处理:(再发一次或者删除重复的数据)

  • 数据丢失或延迟。发送方发送数据seq时会起一个定时器,如果在指定时间内没有接收到ACK seq + 1,就把数据seq再发一次。
  • 数据乱序。接收方上一个收到的正确数据是seq + 4,它返回seq + 5作为ACK。这时候它收到了seq + 7,因为顺序错了,所以接收方会再次返回seq + 5给发送方。
  • 数据错误。每一个TCP数据都会带着数据的校验和。接收方收到数据seq + 3以后会先对校验和进行验证。如果结果不对,则发送ACK seq + 3,让发送方重新发送数据。
  • 数据重复。接收方直接丢弃重复的数据。

但这种操作非常耗费资源,因此ACK有一些优化: 客户端一次给服务器发送多个数据包,当服务器收到客户端的数据包时,不马上发送ACK,而是稍微等一小段时间(约几分之一秒)。在这个过程中服务器可能能收到后续几个数据包,服务器就可以直接按照最后一个正确的数据发送ACK,减少发送ACK的总数。

2.超时重传机制

发送方发送的报文中含有序列号,每当发送一个报文后,就启动一个计时器(RTO),若RTO太小,可能有些报文只是遇到拥堵或网络不好延迟较大而已,这样就会造成不必要的重传。太大的话,使发送端需要等待过长的时间才能发现数据丢失,影响网络传输效率。 由于不同的网络情况不一样,不可能设置一样的RTO,实际中RTO是根据网络中的RTT(传输往返时间)来自适应调整的。当发送一个报文以后,发送方在计时范围以内,如果没有接收到相应的ACK确认报文,那么发送方就会重传该报文。

3.快速重传机制

该机制指的是,发送方一直发送报文,不会每发一次报文就都要等待到这个报文的ACK标志才发送下个报文。 当接收方发现接受的序列号不对的时候,发送连续的3个ACK标志,告诉发送方,这个报文在传输过程中出现了丢包。发送方如果接收到某个相同序列号的三个ACK报文,那么此时立马重发该报文,不用等待计时器的时间结束。

4.滑动窗口

TCP的窗口单位是字节,滑动窗口是指将数据一部分一部分的发送,“一部分”是动态变化的,取决于接收方的接收能力的变化。接收方会将下次希望接收的窗口大小告诉发送方。从而避免一次发送的数据过多或过少。

5.拥塞控制 

 滑动窗口考虑的是发送方与接收方两个端点,而拥塞控制考虑的是整个网络。假设网络已经拥堵,而前面的机制为了保证消息可靠到达,会进行重发的操作,从而加剧网络拥塞。此时TCP使用了拥塞窗口机制。

滑动窗口是理想情况下可发送的数据的规模,但是由于网络等原因,发送的规模往往不能达到滑动窗口的大小。而是使用拥塞窗口为准。拥塞窗口与滑动窗口概念类似,拥塞窗口是根据网络状况调节大小(与拥塞阈值比较)。

当拥塞窗口大小小于拥塞阈值,发送方会进入慢启动模式,即拥塞窗口大小呈指数增长(1、2、4、8...)

当拥塞窗口大小打大于拥塞阈值,发送方进入拥塞避免,窗口大小呈线性增长(32、33、34..)

每当遇到网络拥塞时,会将拥塞阈值减少,然后进入慢启动或是拥塞避免(取决于网络状况)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值