我的mqtt协议和emqttd开源项目个人理解(15) - MQTT消息推送协议应用数据包超时是否需要重发?

 

https://blog.csdn.net/libaineu2004/article/details/80493902

 

今天在看MQTT协议文档,到处关于QoS(Quality of Service)的介绍,文档说如果没有收到对方的PUBREL等确认包,超时后server需要'delivery retry", 一开始觉得理所当然的,重发嘛,丢包,正常。

然后就看到消息重发(Message delivery retry)这一章:

4.2. Message delivery retry

Although TCP normally guarantees delivery of packets, there are certain scenarios where an MQTT message may not be received. In the case of MQTT messages that expect a response (QoS >0 PUBLISH, PUBREL, SUBSCRIBE, UNSUBSCRIBE), if the response is not received within a certain time period, the sender may retry delivery. The sender should set the DUP flag on the message.

上面说TCP在某种情景下下可能会丢包,一想不对呀,TCP能够保证可靠传输的,当然send()不保证对方能收到,但是至少是“尽量能保证”对方能收到。而且是:要么对方应用程序全部收不到,要么就是按序收到数据的。

比如发出去了A包,但是A.ack回包没有收到,超时了。这个时候协议说,server需要"the sender may retry delivery",也就是重传一个A‘ 的第二个包。

不应呀,于是问了问朋友,对方也觉得不应该的,虽然说TCP也不是可靠传输,不一定能保证对方能收到。但它无论如何能够保证对方要么前面后面的都收不到,要么前面的肯定在后面的之前收到。所以这么说来,是不需要重传的。没有必要。

可能协议没有说清楚,也许指的是说客户端挂了,bug了,把消息在对方代码里面丢了,core了什么的。所以查了查邮件列表什么的。找到了一个今年8月份的讨论,总算找到了原因,是文档没有写清楚,目前最新文档时3.1版本,邮件组里面说3.1.1版本已经修改了描述,但还没有发出来。

真正的重发只需要存在于连接出问题断开的情况,比如客户端重连了,而且上次断开之前没有叫我clean session,那server需要重发上次的数据,其实就等于是要补发离线记录一个道理。另外如果有老版本的TCP协议客户端存在,其不支持可靠传输,也需要重发。具体可以看这里的总结,大概的结论是:

1.只要连接没有断开,不需要重传;

2.协议这么写是为了兼容老版的TCP/IP协议,可能那些协议可能有丢包(到达应用层的丢包,不指IP层);

3. 在3.1.1版已修改了表述。

 

 

TCP/IP的超时与重传使用的是“指数退避”的方式。分别为1、3、6、12、24、48和多个64秒。首次分组传输与复位信号传输之间的时间差约为9分钟。

第一次发送后所设置的超时时间实际上为1.5秒,此后该时间在每次重传时增加一倍,一直到64秒,采用的是指数退避算法。一共重传12次,大约9分钟才放弃重传,该时间在目前的TCP实现中是不可变的,Solaris2.2允许管理者改变这个时间,tcp_ip_abort_interval变量。且其默认值为两分钟,而不是最常用的9分钟。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值