Jump to content
  • Advertisement
Sign in to follow this  
TalonSnow

Unreliable UDP packets

This topic is 4800 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

O.K. im confused. I am having no luck in using unreliable packets. I have a player update code that sends out a packet every frame. With a Sleep(0); in it it is sending out a an enormous amount in a second, yet i receive on epacket on the client (which is on the same machine) in about 15-40 seconds. If i use reliable it works fine, and updates right on schedual. yet when more and more users join, if I always use reliable for my player updates it will obviously lag very fast. Can anyone think of anything that would prevent that many unreliable packets sent to not arrive? Heres is the facts from the logfiles Server sent 1,092 unreliable update packets within a period of 40 seconds Client received 5 out of them. :(

Share this post


Link to post
Share on other sites
Advertisement
Hello TalonSnow,

First what network library and on what system are you running on?

Stright socket lib doesn't have reliable udp.

If running on same system udp(or tcp) never goes to network it handle local on system by ways of pipes/internal buffer/files etc control and set up by system.

If sending lots of udp message it your recv buffer is small any packet sent after it is full are thrown away, by nature of UDP.

More info would be nice.

Lord Bart :)

Share this post


Link to post
Share on other sites
im using Raknet. The default MTu size i have set to 1400 so that shouldnt be a problem.

One thing i have noticed when testing around with diff things, is if i disconnect from my hub and plus the internet from the router straight into my computer i get alot more packets received.

Share this post


Link to post
Share on other sites
Ok using Raknet, I never use it before.

the recv buffer I am talking about is at the socket level.
defualt on must systems is not large maybe 2 full size udp (128k) packets.
Since udp is a datagram proto if the buffer is full system will throw away packet it can't store fully in the buffer.

If you client is slow to pull data off the buffer with recvfrom(or what were Raknet uses call this at some point), then the buffer will fill up and message will be thorw away.

If you use a port that is commonly use they you could be get udp packets form other programs coming to.

Raknet should have control to yet you increase recv buffer of the socket.
Also try to have your client do nothing but read packets as fast as it can.

Of these 1,092 packets how big are they?
The bigger they are the faster you recv buffer will fill up with data.
size of MTU is just max size of smallest actual network packet you can send on the network.
If you udp message is bigger (4000 bytes) system will break it apart into many MTU packets and send into 2 1400 and 1 1200. roughly
Theres more of a chance to lose the data this way because if just one of the broken up (1400 byte) packets is lost the whole udp message is disgraded.

Thats why UDP is unreliable.

Lord Bart :)

Share this post


Link to post
Share on other sites
Try changing the Sleep(0) to Sleep(1). My experiences with Sleep on Windows is if the value is zero it does nothing. By using a minimum of 1 you're ensuring a task-switch. Your client is possibly just starved of processing time.

Share this post


Link to post
Share on other sites
ok it is alot better now, but still not very applicable.

What i did. Taking it off my Hub and plugging the ethernet into the computer directly helped alot. Then messing with the sleep timer. It seems if the timer isnt set to a certain point my FPS slowely starts dropping over time. Which would give the overflowing of the buffer idea prob. a good basis.

also I am using unreliable_sequenced. As i dont care if they all arrive, but just that a slow packet wont be slipped in.

setMTU size is what determines the size of which the buffer can hold. This i changed already from the default of around 580 to 1400. This helped some for certain but still having the problems described.

So here is the structure I am sending across so much.


struct playerType
{
char* name;
char* password;
int health;
int moves;
int rank;
int score;
int sector;
int attack;
int defense;
int stealth;
int endurance;
int pistol;
int rifle;
int heavyWep;
int explosives;
int sabotage;
int medic;
int engineer;
int drive;
int fly;
int navigation;
int team;
structInventory weapon;
structInventory armor;
structInventory inventory[20];
};

struct structAmmo //this is just to descibe the loaded ammo inside an object
{
int type; //what type of ammo is it loaded in the object?
int amount; //amount of ammo left
int damage; //damage modification (note this can also be negative)
float armorPenetration; //modifyier on armor penetration on other objects
float chanceToUse; //chances of using this object on another object (i.e. to hit with a weapon)
int misc; //placeholder for anything extra unique in this object
};

struct structInventory
{
int type; //what is it?
structAmmo ammo; //used to store inside another object (i.e. loaded in a gun)
int damage; //dmaage modification (note this can also be negative)
float weight; //weight of object, for use with inventory and total weight able to be carried
float armorPenetration; //modifyier on armor penetration on other objects
float armorRating; //rating of armor this object has
float armorStatus; //amount of armor that is left
int movesToUse; //amount of moves it takes to use this object
int ammoToUse; //ammount of ammo it takes to use this object
float chanceToUse; //chances of using this object on another object (i.e. to hit with a weapon)
int misc; //placeholder for anything extra unique in this object
float minAccuracy; //beginning accuracy
float maxAccuracy; //highest accuracy can get with this object
float accuracyOffset; //time accuracy increases with time
float baseTime; //how much time for this object to be used again
int timeSec;
int timeMin;
int timeHour;
};





Now it is working fine on my computer (not sure if it is really ok, or just because its local) Yet, on a testers who lives in the UK the updates are not being received unless reliable. And even then slow.

Would using a stream produce better results on updating then always sending packets?

I am trying to figure out why it is so slow, to others. I know internet lag can ccount for some of this. Yet, realistically shouldnt they be receiving without a problem as i woudl assume most games send alot more info accross then I am?

Please correct me if im wrong :)

(*and i know I can clean up the code being sent as its not ALL necessary for the client, as in the client wont need to know damage, though it will need to know accuracy, and soem things can be taken out. But, even jsut for testing im not sending too much am i? *)

[Edited by - TalonSnow on June 21, 2005 9:03:18 PM]

Share this post


Link to post
Share on other sites
You're overflowing the UDP MTU. Just the structInventory stuff is using up over 2000 bytes alone. The packets can't arrive at their destination without being fragmented and so they get dropped.

Share this post


Link to post
Share on other sites
ok thanks for the information, im still slow on data types and sizes.

I will work on slimming it down alot and see how it goes.

Share this post


Link to post
Share on other sites
ok it seems much better now to my testers, though the one in UK and the farthest hasnt been on yet to test.

The update code doesnt send the info at all now. It just sends the current time of the server, as well as a list of players in the players sector.

I eleminated the rest by thinking during the game the player only needs to be updated on a few things so far, and put individual sends in the functions where these values accually change then update the client.

Now one of my questions is on the player list that shows all the players sharing the same sector as the player. Right now i have it set to 200 instances. I am not using vectors, is there any way to send only the players that share it, besides sending an individual send on each player, without allocating a max value?
As is my understanding even if there is only 1 player sharing the same space, they server will still send a packet the size of all 200 right since thats what the variable is able to hold? And if there isn't a practicle way to send only the ones i want in one send, is it bad to send one send per player? Note this will only take place in movement, where it will update all players on an additional player, or a player moving out.

Anothe rapproach i can think of would be to only send the player who is moving in or out to all the other players reducing much of the material sending, however, the player itself would still need to get a full updated list.

So any suggestions or tips?
:)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!