[ENet-discuss] Retransmission mechanism of enet

Lee Salzman lsalzman1 at cox.net
Sat Jul 21 18:30:47 PDT 2007

Todd Huang wrote:
> Hello:
>     I am now trying to use the enet to provide a communication tunnel 
> between a multimedia server and the player over the Internet. Since the 
> behavior of the Internet is unpredictable, I try to establish the connection 
> with the reliable feature. In order to test enet's reliability feature, I 
> try to decrease the bandwidth of the Internet and monitor the traffic by 
> using Ethereal.
>     After tracing the captured result, I am somewhat confused and wish 
> anyone can provide your comment.
> 1.  enet will append a 24-byte header before user data, and the sequence 
> number will be put in the last four bytes. Am I right? If it is correct, 
> could anyone tell me what's the name of the data structure of this header? 
> In which header file is it defined?

It's in include/enet/protocol.h

And it shouldn't be 24 bytes last I checked. If you are using ENet 1.1, 
the header size is much smaller.

> 2.  What's the name of the timer and its value enet uses for transmission 
> time-out? Does the timer adopt the backoff algorithm (0.5, 1, 2, 4,....) 
> like the TCP? Or its value fixed?

The initial timeout is RTT + 4*variance. Next timeout is double that. 
Next is double again. Repeat ad nauseum until a limit. If limit reached, 
assume disconnected.

> 3.  According to my assumption, enet will retransmit the un-acked packets in 
> sequence. That is, enet will retransmit the packets (within allowed window 
> size) with sequence number 100, 101, 102,.... if the sequence number of the 
> latest acknowledgement is 99. However, I find that the retransmitted packets 
> are in decreasing order (102, 101, 100). Do I miss anything?

Packets are not sent over the network in any particular order. They are 
sent as soon as possibly can be, in any order. Reordering and sequencing 
happens on the delivery end of things. Doing otherwise would massively 
increase latency, and latency is the enemy here.

It's just that if you're using reliable packets, even if ENet has the 
101st and 102nd packet, if the 100th is missing, then it waits till it 
gets the 100th and delivers it to you before passing you 101 and 102.

For unreliable packets, if it has 101 and 102, it will just give you 101 
immediately, and mark 100 as lost (and never deliver it). There is no 
waiting whatsoever, but it still gives you your packets in order, even 
though it doesn't guarentee the packet will get there. This behavior is 
very important if you're sending a stream of unreliable updates at 
regular intervals (i.e. position updates for a game), where the fact 
that something is lost doesn't matter, only that it's in order.

For unsequenced packets, it will just deliver them all ASAP, in the 
order they arrived, so they are basically... unsequenced.

On top of this, they can all be delivered over independent channels 
which have no sequencing between them.

So, plenty of ways to fling data. More than I personally use, really. ;)

> 4.  Is anyone familiar with the throttle algorithm of enet? Is there any 
> related document describing this algorithm?

ENet keeps track of the average round trip time and variance over a 
given time period based on acknowledgements. It records the lowest 
average RTT and highest RTT variance.

So, given lowest RTT and highest variance from the last time period 
(this is important, you need good averages so can't use current time 
period)... If the RTT of a reliable packet is less than the lowest RTT, 
then throttle goes up. If its greater than lowest RTT + 2 * highest 
variance, then throttle goes down. How much it goes up or down each bump 
(as well as time period) is controlled by 
enet_peer_throttle_configure(), or the default settings which I had 
tuned for POTS-modem use.

The value of the throttle determines the probability ENet won't drop 
your unreliable packets. High throttle means they get through most of 
the time. Low throttle means many will get dropped.

If you specify some decent values for bandwidth on enet_host_create(), 
instead of just 0, then ENet can also limit how high the throttle of 
individual clients will go based on the individual bandwidth limits of 
the client and how much data you're sending back and forth to them.

>     Thanks.


More information about the ENet-discuss mailing list