TCP协议可靠性实现

1. 确认应答机制

  • TCP为每个字节的数据都进行了编号,即就是我们所说的序列号Seq。
  • ACK就带有对应的确认序列号,就是为了告诉发送者,已经收到了哪些数据,下次要从哪里开始发送。

2. 超时重传机制 

(1)情况一,主机A向主机B发送数据,但可能出现网络拥堵等情况,导致数据无法传输到主机B,因此A在等待一个特定的时间段后,还未收主机B的确认应答,就会重新发送数据。

(2)情况二, 主机A向主机B发送数据,但是主机B在确认应答的时候出现问题导致丢包,那么主机A在等待特定时间后,会进行数据的重新发送,但由于主机B事实上是收到数据的,重新发送会有重复数据,所以又可以应用到前面所说的序列号,做到去重效果。

(3)特定时间间隔的确定

  • 最理想的情况下,要确保找到一个最短时间,并且在该时间内确认应答一定可以返回
  • 如果超时时间太长会影响重传效率,时间太短会导致包的重复发送
  • Linux、Windows中,以500ms作为一个单位每次判定超时重发的时间为500ms的整数倍,重发一次得不到应答,就等到2*500ms进行重传,仍不行的话就4*500ms,以指数形式递增,累积到一定重传次数,就判定是网络或者对端主机出现异常,会强制关闭连接。

3. 连接管理机制

(1)详细的三次握手建立连接与四次挥手释放连接过程,可以看上一篇的博客:图解TCP三次握手与四次挥手~

(2)客户端的状态转换

  • CLOSED -> SYN_SENT:客户端调用connect,发送同步报文段SYN;
  • SYN_SENT -> ESTABLISHED:connect调用成功,此时进入ESTABLISHED状态,开始进行数据的传输;
  • ESTABLISHED ->FIN_WAIT_1:客户端进行close调用,向服务器发送结束报文,然后进入FIN_WAIT_1状态;
  • FIN_WAIT_1 -> FIN_WAIT_2:当客户端收到服务器端对结束报文的响应,客户端就进入FIN_WAIT_2状态,然后等待服务器端的结束报文;
  • FIN_WAIT_2 -> TIME_WAIT:客户端收到服务器端的结束报文,进入到TIME_WAIT状态,并发送最后一个ACK;
  • TIME_WAIT -> CLOSED:客户端等待2MSL,进入CLOSED状态。

(3)服务器端的状态转换

  • CLOSED -> LISTEN:服务器端调用listen进入LISTEN状态,监听等待客户端的连接请求;
  • LISTEN -> SYN_RCVD:监听状态下收到连接请求,即同步报文段,会向客户端发送SYN确认报文和ACK;
  • SYN_RCVD -> ESTABLISHED:客户端发回确认报文,服务器端就进入到ESTABLISHED,可以开始数据传输;
  • ESTABLISHED -> CLOSE_WAIT:服务器端收到结束报文,回复报文并进入CLOSE_WAIT状态;
  • CLOSE_WAIT -> LAST_ACK:处理完之前的数据,服务器端就要准备关闭连接,正式关闭时会发送FIN,并进入LAST_ACK,等待最后一个ACK到达;
  • LAST_ACK -> CLOSED:服务器端收到客户端的ACK,彻底关闭连接。

4. 滑动窗口

  • 前面提到的确认应答机制,对每一个发送的数据段, 都要给一个 ACK 确认应答, 收到 ACK 后再发送下一个数据段, 这样做有一个比较大的缺点, 就是性能较差。于是采用滑动窗口机制, 将一去一回的串行的网络传输转变为并行的收发数据 ,主要作用就是 提高网络传输效率
  • 窗口:无需等待确认应答而可以继续发送数据的最大值。 窗口越大, 则网络的吞吐率就越高。
  • 滑动:并行发送数据报时,需要收到ACK响应报文才能确认数据发送成功,而窗口的滑动与否以及滑动的位置,都是由ACK响应报文的下一个序号确定,具体是 滑动到ACK响应报文连续的最大确认序号

5. 流量控制

  • 接收端处理数据的速度是有限的,若 发送端发的太快, 导致接收端的缓冲区被打满,此时持续 发送, 就会造成丢包、丢包重传等一系列连锁反应。因此 TCP 支持根据接收端的处理能力, 来决定发送端的发送速度。
  • 流量控制具体实现:①接收端将接受缓冲区的大小放在TCP首部的“窗口大小”字段,和ACK一起发送,字段越大说明吞吐量越高;②接收端一旦发现自己的缓冲区将满,就会把窗口大小改成一个更小的值通知给发送端;③发送端接收到窗口,会减慢发送速度;④若接收缓冲区满了,窗口直接置为0,此时发送端不再发送数据,但是定期发送一个窗口探测数据段,让接收端把窗口大小反馈过来。

6. 拥塞控制

  • 因为在开始阶段,我们并不了解当前网络状况,贸然发送大量数据会导致网络状况更差,所以使用慢开始机制,先看看网络状态,再适当增加传输速度。
  • 此处引入了拥塞窗口的概念,拥塞窗口初始值为1,随后开始指数型增长,直到到达某个阈值后,变成线性增长。
  • TCP开始启动时,慢启动阈值为窗口最大值,每次发生超时重传,阈值减半同时拥塞窗口置为1。
  • 拥塞控制的实质即为:即可能快的传输数据,但是要避免给网络造成巨大压力的折中方案。

7. 延迟应答

  • 如果接收数据的主机立即返回ACK应答,那么返回的窗口是很小的,但是我们知道,窗口越大网络的吞吐量就越大,传输效相应就越高,而最理想的状态就是保证网络不拥塞的情况下计量提高传输效率。
  • 延迟应答原理就是:接到数据报,不马上响应ACK,等待一段时间后再应答,这样可以增加滑动窗口分大小,并提高网络吞吐量。
  • 数量限制:每隔N个包应答一次;时间限制:超过最大延迟时间就应答一次;具体数量和超时时间是由操作系统决定,一般N取2,超时时间取200ms。

8. 捎带应答

  • 实质上就是合并发送数据报,从而提高网络传输效率。

9. 粘包问题

(1)粘包问题出现原因

  • TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
  • 发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
  • 接收方引起的粘包是由于接收方用户进程不及时接收数据,从而导致粘包现象.

(2)解决方法

  • 实质是:明确两个包之间的边界
  • 对于定长包,每次按照固定大小读取即可。
  • 对于不定长包,①可在包头位置,约定一个包总长度的字段;②在包和包之间使用明确的分隔符,保证不和正文冲突即可。

10. 面向字节流

  • 当创建一个TCP的socket时,会同时创建一个发送缓冲区和接收缓冲区。
  • 调用write时,数据会先写入发送缓冲区,①如果发送字节数过长,会被拆分成多个TCP数据包发送出去;②如果发送字节数太少,就需要等待,等到缓冲区内数据长度差不多时,会发出去。
  • 接收数据时,从网卡驱动程序到达内核的接收缓冲区,然后应用程序可以调用read从接收缓冲区取数据。
  • 因为对于一个TCP连接来说,既可以读数据也可以写数据,那么就是全双工的。

11.TCP小结

(1)安全机制

  • 确认应答机制:ACK+序号实现。
  • 超时重传机制:TCP内部实现,动态计算,以单方向数据传输最大时间*2作为超时时间。
  • 连接管理机制:三次握手建立连接与四次挥手释放连接。
  • 流量控制:使用窗口大小字段,告诉发送端发送数据的大小。
  • 拥塞控制:慢启动,指数增长到阈值开始线性增长。

(2)效率机制

  • 滑动窗口:并行收发数据。
  • 延迟应答:接收到数据报,等待一段时间再响应ACK。
  • 捎带应答:合并发送数据报。

12.TCP与UDP的对比

对比UDP(用户数据报协议)TCP(传输控制协议)
有无连接无连接有连接
是否可靠不可靠可靠
传输方式面向数据报面向字节流
缓冲区有接收缓冲区,无发送缓冲区接收、发送缓冲区都有
首部开销8字节

20字节

连接方式一对一、一对多、多对多的交互通信点到点

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值