Advertisement

UDP/IP Packets And Splitting...

Started by August 31, 2003 02:29 PM
16 comments, last by The Great Sephiroth 21 years, 5 months ago
OK, I have been toying with sockets for a while now, though primarily on my Linux boxes. Now however, since I am an avid GL and C/C++ coder in Win32, I have decided to take one of my older games and redo it in GL, and add multiplayer. I already have a lot of code to minimize network traffic, such as the server only sending data on other players that the player can physically "see", only sending data on world objects when they move, and not when they''re idle, etc etc. I am also restricting player chat messages to 256 characters. However, this is UDP and while a dropped packet should be no problem by itself, if a packet gets split, and/or arrives out of order, I am lost on what to do. So far I have a list of "impulses" that the server sends to the client, and another list that the client sends to the server. Each one means something different, such as 0 from the client means the packet contains connection info (version and CRC), while 0 from the server means that the client version and CRC are fine. Now for the problems I forsee. 1) How do I deal with a packet that gets split? 2) What if a split packet has one packet dropped? 3) In #2, how long do I wait to drop the whole thing? 4) Could I use "send()" and point it to a struct of floats to send the player''s position to the server?? I have some more minor questions, but those are the big ones. Thanks for the help!
-The Great Sephiroth
1, 2, 3) You detect that the entire packet didn''t arrive. When you send a packet over the net, another layer of the stack can divide this packet into frames. I think it''s the Data-Link layer. On the other side, the same layer reassembles the packet. If not all frames arrive then the whole packet is discarded. So you just ahve to check if your application receives the packet at all (if you care).
4) You can send pretty much anything you can create in C++. Everything is converted into a character stream before being sent. For character movements you would likely have some internal structure like this
struct Move
{
int iPacketType;
float fDeltaX;
float fDelyaY;
}sMoveData;

Then what you would send is simply
char* cpsMoveData = (char*)&sMoveData
The structure cast into a character pointer.

Then on the other side you could have a generic structure that has just the type parameter like this
struct Generic
{
int iPackType;
} sGeneric;

And you would call recv or recvfrom with a pointer to a character array of some arbitrary size. Then you cast that char array into type sGeneric. Then you can access the type parameter and figure out what type of packet it is. It it is of type Move then you can recast it into a Move structure and voila you have access to the deltas that you need.

Hope this helps,
Webby
Advertisement
Thanks, you REALLY cleared a lot of my worry up, but I want to be clear on just ONE thing before I off and go beyond this point. Even if some guy on a 14.4k modem sends a UDP packet that is say, "char Message[8192]", my "recv()" function on the server won''t get the packet until it has been COMPLETELY reassembled by the system? If that is the case, AWESOME. If not, I''m back to worrying about getting the first 256 chars on one recv() then the next 128 on another, etc etc.

My final worry is this. My server is setup to handle up to two-billion players (though I plan on limiting that on my current box and line). Needless to say, they''re all going to be constantly updating their positions and such. Is it possible that in a single "recv()" on the server, the server could get a whole packet from guy A and part or all of a packet from guy B? That''s about the only other worry I have, and since I am on a 200mbps ethernet connection to the server, I can''t simulate 56k speeds. Thanks for all your help!


-The Great Sephiroth
-The Great Sephiroth
maybe you want to use the max packetsize of udp packets and then manage them by you app !? this would reduce a resend of 8kb when only one 0,5kb packet is lost...

i think getsockopt with the optname SO_MAX_MSG_SIZE will give you the value for this, but its maybe something different (sorry ive begun network programming yesterday )


T2k
I''ve been doing it for almost a year now, and I''m not sure if that works under Windows. I know you can''t set a non-blocking socket in Windows because fcntl.h contains DOS info, not socket. And the help on Winsock is VERY limited. MS just HAD to change things around on their OS, even if it was just capitalizing a name or something.


-The Great Sephiroth
-The Great Sephiroth
quote:
Original post by The Great Sephiroth
I know you can't set a non-blocking socket in Windows because fcntl.h contains DOS info, not socket.


#include <winsock2.h>...// make non-blockingu_long yes = 1;retval = ioctlsocket(m_Socket, FIONBIO, &yes);if (retval == SOCKET_ERROR){  ...}  


[edited by - foofightr on August 31, 2003 7:57:42 PM]
Advertisement
Yes but I thought winsock2 was incompatible (or didn''t work right?) on 95? I know it works on 98SE and later, but I was trying to code the engine to run on all platforms of Windoze. With just "winsock.h" I tried and could never get it to work though.
-The Great Sephiroth
quote:
Original post by The Great Sephiroth
And the help on Winsock is VERY limited.

what are you talking about? i think the only thing that is more prolific than porn on the internet is winsock tutorials! try google, or even just the articles and resources section here at gamedev.net...

--- krez ([email="krez_AT_optonline_DOT_net"]krez_AT_optonline_DOT_net[/email])
Yeah, in "Visual ". I am not a Visual kiddie who uses IDEs because I don''t know anything about actual coding. I do 100% of my work in Wordpad. I''m not trying tod iscourage new programmers from using these Visual IDEs, because they are a GREAT newbie utility, and would have helped me way back when I started coding for the 6502 chips (1.8MHz Atari 400/800 chips). However, in dead-on comparisons, the applications produced by these Visual IDEs generally get MUCH lower performance than hand-coded ones because they are not optimized and the code is often VERY sloppy and hard to follow.

Anyways that''s off-subject. I am doing this app primarily in C, and since most tutorials or infos on Winsock are for Visual C++ or Visual Basic, they''re useless to me. I''ve toyed with C++, but it''s useless if you already know C. The way I see it (and have proved to several friends) is this: Your harder to follow C++ code simply gets converted to plain old-fashioned C before being compiled, so if you know C, stick with it. C is easier for most people to follow anyway. And the whole "classes and inheritance is a C++ thing" is a myth. A class and a struct are identical, only the struct has all members public by default, whereas a class makes them private by default.

Sorry if I rambled here, didn''t mean to. I have looked for tutorials and the only one I found that was what I was looking for was here. It was the first one listed, by Beej. It''s what I used to get into coding TCP/UDP. Very easy to follow, in plain C, and it is ANSI so it works on Windoze or Linux. It''s hard finding good tutorials like that any longer. That''s why I regular this site and the one I admin three boards at. I don''t know if I should post the site name/address here though, because I don''t want to get in trouble for spam :D!

-The Great Sephiroth
-The Great Sephiroth
Good thing this is not a very frequented forum, because you opened up a can of worms... several cans, in fact. Suffice to say I think you''re wrong about a lot of things...

What I will say is this. Even if winsock2.h isn''t available on Win95, who cares? It''s a dead platform, even Microsoft has stopped supporting it. The only people who still use it are people who don''t know any better.

This topic is closed to new replies.

Advertisement