Loading...
墨滴

jasonj333

2021/04/07  阅读:15  主题:红绯

通信的触发方式

通信过程,本质上只有两类:事件触发(Event trigger)和定时器触发(Timer trigger)

以TCP连接为例:

事件触发

A主动发起对B的tcp连接(SYN),这是事件触发,是A创建socket调用connect()函数触发tcp连接

定时器触发

如果SYN在发给B的过程中丢失,还需要A后面的用户重新发吗?这样的话tcp协议栈也太不友好了。事实上tcp会缓存用户的连接指令,同时开启一个重传定时器,定时器超时,没有收到ACK+SYN,tcp会自动重传连接指令,这就是定时器触发

事件触发

B收到A的SYN请求,就会发ACK+SYN,这是事件触发

定时器触发

B发送ACK+SYN时同样担心丢失,所以B也会启动一个重传定时器,如果在超时时间内没有接收到A的ACK,说明B的ACK+SYN丢失,触发重传动作。如果收到ACK,则关闭定时器

事件触发

A接收到B的ACK+SYN,这是一个外部事件触发的动作,触发了:

  • 关闭重传定时器
  • 发送ACK
  • 将TCP状态更新为Established

这里A在发送ACK后要不要启动重传定时器?

不需要

你想,如果启动了重传定时器,而B并不会对单独的ACK作为ACK响应,除非此时B有数据发送Data+ACK,如果B只接收数据而不发送数据,那么这个ACK不会有对应的确认ACK发送给A,那么这个重传定时器超时后又会发ACK给B,无限循环下去

为什么A发送ACK不需要关心是否到达B呢?

因为A发送ACK就已经进入Established,只要A发数据,就是ACK+Data,这个ACK+Data才会启动重传定时器

对于应用层提交给tcp的数据,这是事件触发,触发的动作是:

  • 发送数据,并缓冲数据
  • 为数据启动重传定时器

如果接收到对方ACK,事件触发的动作是:

  • 关闭定时器
  • 释放缓存

如果定时器超时也没有接收到ACK,则定时器触发,动作是:

  • 重传数据
  • 记录重传次数

如果重传次数满,比如重传8次,则是事件触发,动作是:

  • reset或关闭tcp连接
  • 通知应用层出错

总结

整个通信过程只需要一次用户输入(用户事件),接下来的通信过程全部依赖事件触发,定时器触发而产生的动作自动完成,不管顺利与否,无需用户干预


jasonj333

2021/04/07  阅读:15  主题:红绯

作者介绍

jasonj333