Il 19/05/2023 17:14, Ed Prochak ha scritto:
> On Friday, May 19, 2023 at 5:42:14 AM UTC-4, pozz wrote:
>> I know TCP is able to guarantee the delivery of messages from sender to
>> receiver, without corruption (thanks to checksums), in order and without
>> duplication (thanks to sequence numbers).
>>
>> So I'm confused when I read something about MQTT QoS. For example, QoS 1
>> (at least once) uses ack (PUBACK) and retransmissions (with packet ids)
>> to guarantee that the message is delivered at least one time.
>>
>> I'm wondering how this is possible over a TCP connection that uses the
>> same technique of ack and sequence numbers.
>>
>> From what I know about TCP, if some data isn't well acknowledged by the
>> receiver, the sender automatically resends the packets not acked. This
>> is performed by TCP/IP stack or kernel, without the application knows
>> anything about this.
>>
>> It seems to me it's impossible that a MQTT client needs to resend a MQTT
>> message because it wasn't received by the broker. If this happens, TCP
>> should signal the error to the application that should close and try to
>> reopen the connection.
>
> TCP is only one of the lower levels of the protocol stack.
> Data can sometimes be lost in the higher levels.
In this case, there's only one higher level, that is MQTT application.
How an application running on a machine could lost something? Network
links aren't reliable, but applicaions running on a processor are reliable.
Do you think about application crash or an entire machine crash that
needs a reboot? In this case, after the reboot, the MQTT application
usually doesn't know anything about the previous connection, timeout and
lost messages... except it saved something on a non volatile memory.
> Secondly, there is the issue of resend timeouts. If TCP fails to deliver
> the message past the MQTT retry time limit, then MQTT will resend the
> message.
What happens in this case? Suppose one TCP fragment with a single MQTT
message (just for simplicity) sent by a client to the server (the
broker) was lost. After a TCP timeout, the network stack autonomously
resend the fragment until an ACK is received. Even if the MQTT
application resend the MQTT message *before* TCP timeout, it will not be
sent by TCP layer until the previous fragment is acked.
Maybe, more exactly, on the receiver machine, the TCP layer will not
pass the resent message to the application (the MQTT broker) before the
lost TCP segment is received as well. When the lost TCP fragment is
received, the broker will receive two MQTT messages: the "original" and
the resent ones. I think it's impossible for the broker to receive the
second transmission without receiving the first.
So it seems to me the retransmission made at the MQTT level is
completely useless... but I think I didn't get the real point here.