As a last note, it’s easy to see that we can easily implement at-most-once delivery semantics and at-least-once delivery semantics.
We can achieve the at-most-once delivery when we send every message only one time, no matter what happens. Meanwhile, we can achieve the at-least-once delivery when we send a message continuously until we get an acknowledgment from the recipient.