Reliable UDP Library

Hello,

I have just sent a project proposal for a UDP network library which is able to perform Reliable/Unreliable/Sequenced/Unsequenced packet delivery on UDP. It is a port of the popular enet library for C. So, if that interests you, maybe you should read the proposal for a more comprehensive description. It is at:

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=Proposals;action=display;num=1114748790

If you like it a vote will be highly appreciated ;D.

Thank you,

Dizan

I already voted yes :slight_smile:

Sounds like very handy thing to have around and i very much like the idea that you are going to implement an existing protocol rather then invent Yet Another Protocol.

Im personally not sold on the advantages of hand-tuned reliable communciations protocols over TCP in many cases, but it sounds like your going to have some inetresting knobs on it and i know some people just really get off on the idea of reliable UDP :slight_smile: :slight_smile: :slight_smile:

I’d like to see something like ‘discardable reliability’.

IMHO there are three basic use-cases for network messages in games.

1.) Event-like, store-forward message. Like ‘a bullet has been shot’. Must be reliable.

2.) Structural changes. A player entered, health descreased, a door opened, a party formed, … . All things that a new player entering after that happened will need to know as well. Messages must be reliable and backed up by some server structure that can be pushed to new clients.

3.) Operative data like position updates. For many brute force mechanism (sending 10/s) dont have to be reliable. For things like dead-reckoning (as I use it in FlyingGuns), has to be reliable. The dead-reckoning allows to send NO data for many seconds (e.g. for a straight flying plane). But this requires reliable transmission. OTOH, in tight-turning dogfights 3 or more messages/sec have to be send. In this case, it would be no problem if one gets dropped in favor of the following that need to be send anyway. Even worse, in TCP the lastest has to wait until the discardable was transmitted. Double bad.
Here I’d need a ‘transmit-reliable-until-next-transition-is-initiated’.

Is something like that provided by eNet?

Hello guys. Thank you for the vote Jeff and sorry for not answering before, but I was more concentrated on the project approval forum.

Herkules, regarding your questions I must say that eNet (and thus JeNet at this moment) is relatively low level:

[] You can send individual packages and label them as reliable/unreliable.
[
] The library handles all sending/aknowledge/resending for reliable packages.
[] The library splits up large packages in smaller ones according to the network’s MTU (Maximum Transmission Unit) and reassembles them in the listener’s side.
[
] You may limit incoming/upgoing bandwidth. Unreliable packets will be discarded if the limit is exceeded.
[*] Other network features as lobying, compression, service discovery, etc. are not handled by eNet.

So, going into your particular scenarii:

Sorry, I didn’t finish the last one, I will continue to answer Herkule’s questions:

  1. eNet/jenet may be applied in a straightforward fashion to send short/reliable event-like packets. eNet’s reliable packets are lighter than TCP connections.

  2. Big packets containing structural data, global flags and the like may be sent using eNet protocol. However, the library does not provide explicit mechanisms to maintain a distributed world’ state. Such a facility may be built on top of the protocol by the developer. JeNet, in the other hands, will try to encompass some higher level mechanisms in further releases.

  3. Unreliable/high traffic data is all eNet is about! That’s the case of the tight turning related messages, moreover, switching between reliable / unreliable modes consists simply in applying a flag to particular packet.

Well, I hope this will answer your questions,

Dizan

p.s. I’m not sure about the meaning of ‘discardable reliability’. Does it mean switching freely between reliable/unreliable modes for new sent packets? or is it something like interrupting the reliable transmission of a multipacket message before it’s ended

Sounds good.

From the networks point of view, (1) and (2) are basically the same thing. HeadQuarter is in fact that high-level structure.
Maybe (2) is different from (1) that order might be important.

The latter. Or think of a buffer that can be modified as long it hasn’t really been transmitted.
Position update is a very good example. My dead-reckoning requires guaranteed submission … as long as no message has to follow anyway. The existance of the newer message allows the older, potentionally not yet delivered message to be descarded in favor of the new one.

I always considered high-traffic as bad. Achieving low-traffic normally implies reliability.

But thats a design goal … Quake e.g. sends as much as possible, occupying the line completely. Message loss is part of the principle.

In contrast, FlyingGuns sends close to nothing. But always reliable.

What is better? A matter of taste.

(This is a very basic development pattern: render as fast as possible in a tight loop occupying the CPU completely, or running with ‘sufficient’ framerates, leaving CPU for other apps? Fullscreen or windowed?)

[quote]My dead-reckoning requires guaranteed submission … as long as no message has to follow anyway. The existance of the newer message allows the older, potentionally not yet delivered message to be descarded in favor of the new one.
[/quote]
Ok, I think I’ve got it. Let’s look at how JeNet handles unreliable packets:
For every comm channel (you may have many with the same peer), all unreliable packets which are older than the newest received packet are silently discarded. When a new unreliable packet is received it is processed and no acknowledge is sent.

In order to implement discardable reliable (d/r) packets a similar reception mechanism may be used: when an old ‘d/r’ packet is received, it is discarded, but if it is new it is processed and an acknowledge is sent.
For the sender things are as follows: Only the last ‘d/r’ packet is kept in the outgoing queue. If a ‘d/r’ packet has been sent and the acknowledge has not been received we proceed as follows: if a new ‘d/r’ packet exists in the outgoing queue, this packet is sent, if not, the packet which was not acknowledged is resent (wow, that was lots of ‘if’s’).

I think that such a schema is interesting, it switches between reliable/unreliable modes in response to low/high network traffic over a given channel. I think that I’ll include this as a new feature, but that will be after being sure that the existent eNet-compatible features are stable enough.

In my case, I am using a physics engine which may behave slightly differently on different computers. Since I can’t rely on it to be discrete, the UDP model of “don’t care if a few get lost” suits quite well, plus there is the speed increase due to no re-transmits. I do have a TCP channel open as well though, for once a second - timing isn’t as important communication. Horses for courses I guess.

Will.