Jump to content


UDP networking


11 replies to this topic

#1 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 10 November 2011 - 11:43 AM

I have a game that uses UDP for it's comms

One end sends events to the "server" which updates the game state vector then transmits it.

This works really well, actually I am amazed at how well it works even on low end devices

My problem is coming up with a clean way of closing down the comms at the end of the game.

At the moment I send a QUIT event, then close down the connection.

Of course that is bollocks as there is no guarantee that the QUIT event will reach the target.

So I thought about sending back an ACK to the QUIT, but it's the same problem, no guarantee that the ACK will be received.

Anybody found a way around this that doesn't involve sitting there sending quit events for a couple of seconds?

#2 alphadog

    DevMaster Staff

  • Moderators
  • 1716 posts

Posted 10 November 2011 - 03:40 PM

Well, nothing from the server can be trusted to get to the client or vice versa, right? That's inherent in basic UDP.

So, your solution starts at the client side only. Essentially, the only thing you can do is a) some sort of countdown-to-close mechanism which is reset upon packet receipt, and/or :) some active ping/pong between client and server, or c) use a real protocol, like TCP. :sneaky:
Hyperbole is, like, the absolute best, most wonderful thing ever! However, you'd be an idiot to not think dogmatism is always bad.

#3 }:+()___ (Smile)

    Member

  • Members
  • PipPipPip
  • 169 posts

Posted 10 November 2011 - 05:22 PM

Usually server sends gameworld updates on regular basis, say every T ms. So send QUIT to server and begin waiting up to 2*RTT+5*T ms. If server ACK has received then all OK. If regular gameworld update message has received after 2*RTT of waiting then consider QUIT message as lost and repeat whole process. If nothing has received between 2*RTT and 2*RTT+5*T then consider link as dead and forget about graceful shutdown (server will drop connection by timeout).
Sorry my broken english!

#4 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 10 November 2011 - 06:03 PM

TCP/IP is the devil, when I send data I want it sent now!

I don't want it to be put in a cache and held until some random time in the future

yuck, tried it, it sucks for realtime games.

I guess the nature of UDP means I have no choice but to add a wait and just sit sending the quit message and waiting for an ack.

Cheers guys

#5 alphadog

    DevMaster Staff

  • Moderators
  • 1716 posts

Posted 10 November 2011 - 08:59 PM

Well, there are "halfway-to-real" protocols/libraries you could look at for inspiration, like UDT, ENET and such...

PS: I'm just bugging you. But, I do find lots of people frequently re-adding about 50-80% of TCP back in, though.
Hyperbole is, like, the absolute best, most wonderful thing ever! However, you'd be an idiot to not think dogmatism is always bad.

#6 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 11 November 2011 - 01:33 PM

Yes I know,

I started a "reliable UDP bidirectional comms" system, after about a day of coding I decided I was just writing my own TCP stack

So I junked that and I have been happy with the results thus far, I just hate having to put in delays and resends just in case...

#7 moe

    Valued Member

  • Members
  • PipPipPip
  • 276 posts

Posted 11 November 2011 - 05:42 PM

I haven't had a chance to toy around with networking, but by the sound of it, I would try the following strategy:

The client can quit at any given time. When he does so, he sends a QUIT to the server just in case to let the server know. Then the client immediately shuts down without waiting for a response.

The server expects regular input form the client as to synchronise the game. If a QUIT arrives the server immediately acts upon it without sending an ACK back to the client, since the client is no longer there anyway. If no input from the client arrives at all for a certain amount of time, the server considers the client as "dead" and assumes the client did quit and acts accordingly.

Or do you think this would mess up the connecctions and prevent a gracefull shutdown all together?

edit: I just noticed this is similar to what }:+()___ [Smile] suggested... Never mind then.

#8 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 23 November 2011 - 08:47 AM

I ended up doing something similar to that, and it seems to be working.

I've put the game into conformance test now and will let you know the results.

They should be interesting as the game runs on about 20 devices, we should get some interesting data about UDP networking on mobile devices from it that may be useful in the future.

#9 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 29 November 2011 - 10:06 AM

Okay, I have now got back some test reports.

The code works well in most cases, some devices do not support the discovery technique we use, they just fail to see other devices running the game, they don't crash though which is good.

The one thing that has caused a problem is that UDP being connectionless, other devices can legally transmit on the same port, so it is possible to get rouge packets.

To get around this I have added a checksum to all data packets and I ignore any packets with a duff checksum.

Speed looks good though, the HTC desire seems to handle the network traffic very well.

#10 }:+()___ (Smile)

    Member

  • Members
  • PipPipPip
  • 169 posts

Posted 30 November 2011 - 08:49 AM

View PostStainless, on 29 November 2011 - 10:06 AM, said:

To get around this I have added a checksum to all data packets and I ignore any packets with a duff checksum.

I think some sort of encryption required to protect from cheat programs.
Sorry my broken english!

#11 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 30 November 2011 - 09:24 AM

In the general case I would agree, but in this case I am not going to bother.

It's not the sort of game that people will bother cheating

#12 Stainless

    Member

  • Members
  • PipPipPipPip
  • 582 posts
  • LocationSouthampton

Posted 03 December 2011 - 10:23 AM

TCP has massive unavoidable delays outside my control. Some platforms will only transmit a packet when it gets to some fixed size, this is absolutely no use for real time games.

The problems with UDP can be worked around.

At the moment I am trying to fix a bug that happens about once a day when a packet comes in that is of legal format and size, but is either not from my game, or is massively corrupted.

It's really hard to track down as it only happens about once a day, but it has happened on multiple platforms, so it's not just my machine.

The underlying transport layer is still being written. Eventually it will offer encryption and a hmac-sha1 implementation.

At the moment I am using a packet number and a checksum to make sure the packets are in the correct order and belong to me.

The checksum is my own equation, so a packet with a standard CRC32 on the end will just be treated as a corrupt packet and ignored.

Even with all the issues, UDP is the way to be





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users