Author Topic: (to the programmers) Why use UDP?  (Read 3165 times)

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #15 on: December 09, 2003, 04:19:40 am »
Quote
Originally posted by ChrisM
As far as I can see it in the PS source code, the client sends absolute coordinates but the position is first valided by the server meaning the server checks whether the client could get to this position since last known position in the elapsed time between the two packets.

Yeah, sanity check.  That\'s another perfectly good way to do it.  I don\'t do a sanity check because I only transmit keypress data, there is no way for clients to tell my server \"I am *here* now\", so there\'s no need for one.  Different solutions to the same problem :)

Quote

I now started planning my network system und my packets are also relatively huge, except of course packets like special commands but the occur not very often and it wouldn\'t be profitable to cache them and wait for another packet to pack them together...

Don\'t get them too big.  Your practical limit on UDP packets is about 1K.  Beyond that and you risk routers splitting up the packets into chunks, which is a certain formula for many lost packets :)  My packets tend to run in the 50-200 byte range, except for file transmition (patching) which max the packet sizes at 1K.

Quote

Hmm... PS has a very complex network engine.

As for all the rest of your post, you\'ll have to get info from the PS team (if they\'ll give it).  I\'ve not looked at the PS code, nor do I intend to.  I\'m sure it\'s very good code, don\'t get me wrong, but I\'m sure they wouldn\'t want me using their code concepts in my very non-open source codebase :)  So I don\'t even give myself the temptation of looking at what they\'ve done by even downloading it, heh.

Vengeance

  • Veteran
  • *
  • Posts: 1452
    • View Profile
(No subject)
« Reply #16 on: December 09, 2003, 01:41:24 pm »
I haven\'t measured our average message size, but I would bet our average message size is around 25 bytes.  Our dead reckoning system sends positions, velocities, angles and angular velocities and gets all that in 25-30 bytes.

Since many players are being updated each second, merging packets *really* helps network efficiency.  By merging them, you only get per packet overhead on the merged version.  So you get 10-20 bytes of overhead per 750 byte message, instead of 10-20 bytes of overhead per 20 byte message, which is 3% overhead instead of 50%.

In a smaller game, CPU utilization may be more of a factor but in an MMORPG, merging short packets is definitely worth it, and I really don\'t think it takes much CPU overhead anyway.

Just my $0.02,
Venge

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #17 on: December 09, 2003, 03:50:34 pm »
Hi,

again thanks for your helpful answers!

I think, now it\'s time for me to start planning my UDP system, I\'ll start with a very simple std::vector or std::list for the clientlist and only one receive()-function with a short queue in its own thread.

But Planeshift source code is sometimes a bit irritating... for example I wonder why the overloaded network classes (NetBase & MsgHandler) for the server are in the server\'s directory, but those for the client are in the netlib?

So, I\'ll create the first source code line now...
Thanks for your help!!

ChrisM
Please excuse my bad English :)

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #18 on: December 09, 2003, 04:45:56 pm »
Good luck, Chris!  Let us know how it goes.

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #19 on: December 09, 2003, 06:15:28 pm »
Hi,

argh, one question left:
Is there any limit under this there is no fragmentation or something? Or is it theoretically possible that a two byte packet is split up into two one byte packets? (yes, I know, this won\'t happen, but I am talking about the theory :) )

ChrisM
Please excuse my bad English :)

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #20 on: December 09, 2003, 09:57:24 pm »
You prompted me to go look it up.  To my surprise, it isn\'t 1K like I thought it was, it\'s 512 bytes.

Which means packets <=512 bytes won\'t fragment.  Packets > 512 bytes *might* fragment (depending on the router hardware they pass through to get to their destination).

Note that fragmenting is not necessarily a disasterous thing.  It just means there is more chance of losing a part of the packet in transit (in which case the entire packet will be discarded).  You don\'t have to put the packet back together or anything.  The UDP network protocol will do that for you.  As I said, my patching packets are 1K, so they might very well be fragmenting without me having ever known it.  And I probably won\'t change that.  Even though I basically have twice the possibility of losing a packet, so what?  Patch packets are reliable/ordered sent and it\'s not a time critical packet anyway (when players are patching they expect to have to wait a few minutes).

I better go back and make sure my play packets are under that limit though :)  I could have sworn it was 1K rather than 0.5K, heh.
« Last Edit: December 10, 2003, 03:54:00 pm by RonHiler »

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #21 on: December 09, 2003, 10:52:29 pm »
Hi,

wow, thanks for your cool post, where do you look up things like this? I tried to read in the MSDN for UDP, but there are not very much useful informations.

Did I understand the whole thing?
When a packet is fragmented by one router which routes the packet to its destination, the beginning and the end of the packet may get to the receiver and the middle is missing?
Could it for example be, that a 2048 byte large packet is fragmented and the two middle packets (assuming the packet is split in 512 byte large ones) are missing... will than recvfrom() return 1024 and return just the 512 byte large first packet and the 512 last byte?

ChrisM
Please excuse my bad English :)

RonHiler

  • Traveller
  • *
  • Posts: 49
    • View Profile
(No subject)
« Reply #22 on: December 09, 2003, 11:53:18 pm »
Quote
Originally posted by ChrisM
where do you look up things like this? I tried to read in the MSDN for UDP, but there are not very much useful informations.

http://www.gamedev.net

Use it often.  You can find *anything* there :)

Quote

Could it for example be, that a 2048 byte large packet is fragmented and the two middle packets (assuming the packet is split in 512 byte large ones) are missing... will than recvfrom() return 1024 and return just the 512 byte large first packet and the 512 last byte?

Not quite.  UDP has no guarantee of delivery or ordering, but it does have one guarantee.  That if you get a packet, it will be whole and in internal order with itself.  Thus, if a packet fragments, the UDP layers of network protocol will put it back together on the other end before you ever see it.

What this means in terms of missing fragments though is that if one fragment gets lost, the *entire* packet is discarded.  Thus, if you fragment into 10 segments, and you get 9 of them, it is the same as if you lost the entire packet.  This is why large packets will get lost much more often than small ones.

Thus, to answer your example, recvfrom() will never give you a completion notification (or whatever is appropriate for the particular network model you are using, for MM games, you *should* be using completion notifications) for that particular packet, since you lost two of the four fragments. It is the same as if it never arrived at all.

Vengeance

  • Veteran
  • *
  • Posts: 1452
    • View Profile
(No subject)
« Reply #23 on: December 10, 2003, 06:27:11 am »
The ones in the common directory are not in the client directory because they are shared by the client and the npc superclient.

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #24 on: December 10, 2003, 03:00:40 pm »
Hi,

ok, now everything makes sense. :)

Thanks for your answer. I can\'t believe that just before a week I really wanted to use TCP for my network system. :)

Now I just hope, that the \"invalid\" packets (> 512 bytes) in my buffer, won\'t jam it but be deleted after a few seconds.

So, now it\'s really time to start implementing my network interface! ^^

Thanks again for all your answers!

ChrisM
Please excuse my bad English :)

Vengeance

  • Veteran
  • *
  • Posts: 1452
    • View Profile
(No subject)
« Reply #25 on: December 11, 2003, 01:41:39 pm »
In PS, the networking layer splits apart messages bigger than the allowed size into multiple packets and reassembles them on the receipt side.

Starting to understand why there is so much code and complexity in PS networking?  ;-)

- Venge

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #26 on: December 11, 2003, 03:31:57 pm »
Hi,

Quote
Starting to understand why there is so much code and complexity in PS networking? ;-)

Yes. :)

But why do you separate MsgHandler and ClientMsgHandler since there are no other MsgHandlers? However, I think it\'s for future expansion (to perhaps implement a ServerMsgHandler), isn\'t it? :)

And why do you store everything in those binary trees, even if a linked list would make much more sense, in my opinion (for example the list of the guilds).

ChrisM
« Last Edit: December 11, 2003, 03:40:00 pm by ChrisM »
Please excuse my bad English :)

Vengeance

  • Veteran
  • *
  • Posts: 1452
    • View Profile
(No subject)
« Reply #27 on: December 12, 2003, 06:53:52 pm »
MsgHandler is designed to work for any number of connections.  ClientMsgHandler works for only 1 connection, so it is much easier/simpler.

Binary Trees are used because they are faster to search than linked lists.  Thus they have O(log n) sorted insert time and O(log n) retrieval.

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #28 on: December 12, 2003, 11:11:49 pm »
Hi,

great, I understood it! :) (I first didn\'t notice that you overload == and comparision operator for all classes that are stored in a tree, so I wondered how you sorted the objects in the tree *g*)

OK, just one last question (I promise it\'s the last ;) )...
Why do you use so many different Message structures? I mean, all those messages derived from MessageCracker are obviously, but what\'s about the other message classes?

I mean, what\'s the different between psMessage and psNetMessage and between MessageEntry and psNetMessageEntry?

ChrisM
Please excuse my bad English :)

ChrisM

  • Traveller
  • *
  • Posts: 15
    • View Profile
(No subject)
« Reply #29 on: December 13, 2003, 06:49:49 pm »
Hi,

ok, I think I got it now.
netpacket.h is for a part of a message, meaning one UDP packet sent over the network.
message.h is for one merged packet, normally consisting of one netpacket (but can be more if message size > 512 and this packet was automatically splitted by the PS client on the source computer).

Does it work like this?

ChrisM
Please excuse my bad English :)