<br><br><div class="gmail_quote">On Thu, May 24, 2012 at 2:48 AM, Emmanuel Rivoire <span dir="ltr"><<a href="mailto:manu.n02@laposte.net" target="_blank">manu.n02@laposte.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello,<br>
<br>
I have been using DirectPlay from DirectX9 since 6 years in my games and have been pretty happy with it since then, except I cannot use it on Mac OSX.<br>
<br>
So I've decided to give Enet a try and I just had a deep look at Protocol.c & .h .<br>
<br>
DirectPlay gives a packet overhead of 4 bytes for unreliable & unsequenced messages.<br>
ENet overhead is 10 bytes (without the optional stuff) for this kind of messages.<br> </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
In a general way, ENet protocol header always contains : peerID (on 9 bits) and dataLength on 16 bits.<br>
As far as I know, dataLength is already in the UDP header ( <a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol" target="_blank">http://en.wikipedia.org/wiki/<u></u>User_Datagram_Protocol</a> ) and incomplete packets are dropped, so there's no need to have it within ENet header.<br>

peerID should be deducted from packet's sender IP & Port which are in ENetHost::receivedAddress .<br>
<br>
That'd be already 3 bytes saved on each packet in all cases of use of ENet.<br>
<br></blockquote><div>The length is needed because ENet does all sorts of aggregation. The packet boundaries are not 1:1. If you have 10 ENet packets in one UDP protocol packet, well, there's no way to find the packet boundaries without length. This would only be possible for the last ENet packet in a protocol packet, but you are still subject to one final caveat with this that makes it not really worth it... Packet lengths themselves as reported by UDP are not reliable: routers are free to fragment, chop up, etc. packets as will, as is the OS itself before it even sends it to the router, and the OS on the receiving end even as it hands the packet off to the user. By the time the packet gets to you, you have no indication that this packet mangling happened without one of two mechanisms: either a checksum or a length. So length has multiple useful functions here.</div>
<div><br></div><div>The peer id is useful because it speeds up dispatch a lot and also allows the possibility of a connection migrating to a different port in case of NAT trickery or other things.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Moreover, I'm planning to remove ENetProtocolSendUnsequenced::<u></u>unsequencedGroup which is not mandatory at ENet level (this is an arguable opinion ;) ), mainly because I already have the attached functionality in the high level part of my network code, but using less bits, so it's redundant and less effective at ENet level.<br>

2 more bytes saved.<br>
<br>
Lastly, if I understood the code correctly ENetProtocolSendUnsequenced::<u></u>header::reliableSequenceNumber isn't needed (it's always set to 0), so that's 2 bytes wasted (only for unsequenced message case).<br>

<br></blockquote><div>Unsequenced is not simply a normal UDP packet, it is unsequenced, but still not redundant, not quite what you're thinking. It was done this way mainly for uniformity with the other packet types to keep things simple; conceivably you could squish the unsequenced group number into the reliable sequence number space or if you don't care about redundant just remove both somehow. On the other hand, I'm not really interested in breaking protocol compatibility for all users at this point over a feature that isn't really of central utility to most users. In the future I could maybe implement a truly unsequenced/redundant (= truly unreliable) packet type if there was ever sufficient demand, but I think the current unreliable type is the main backbone packet for most people and is generally the most efficient type to use anyway - there is no real efficiency gain from using unsequenced in the current protocol, it's just a semantic thing for when you really need to violate the packet sequencing restrictions for some reason.  </div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So we're now down to an overhead of 3 bytes = 1 byte for flag (in upper part of peerID, with 1 bit free) + 1 for command number (with 4 bits free) + 1 byte for channel ID.<br>
So I'm going to stuck the channel ID in the 4 free bits of the command bytes, and the overhead will be of only 2 bytes.<br> </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

I'm not a network specialist, so maybe I got something wrong, so please let me know if I did something incorrect, especially if I overlooked something.<br>
<br>
And globally, does it sound doable in a timely fashion ..? I hope to spend only a couple of days to do all of that.<br>
<br>
But for now, I'm going to begin by converting my mid-level network code from DirectPlay to ENet, as it's the 1st step on the road..! ;-)<br>
<br></blockquote><div><br></div><div>So the main changes you're left with is you could save that one byte of space for the peer id, and conceivably up to 4 bytes in the unsequenced packet's header by removing the unsequenced group functionality (2) and not including the reliable sequence number (2). So between those two if it's a substantial use case for you you could save 4-5 bytes per unsequenced user packet if it is really an important use case for you. Though I don't think I can do this for the general ENet because it would break compatibility with older versions and all the hassle that causes. You are of course free to make these changes in your own project as that's why I kept the source code small, understandable, and open in the first place: I did want it to be a library that people could dig in and make whatever personal customizations they needed for their project.</div>
<div><br></div></div>