Advertisement

Are sockets full duplex?

Started by July 14, 2003 10:42 PM
30 comments, last by WebsiteWill 21 years, 6 months ago
Just found this helpful and interesting bit of info from "Unix Network Programming" page 398, "...there is no actual UDP socket send buffer. The kernel just copies the application data and moves it down te stack, prepending the UDP and IP headers. Therefore an output operation on a blocking UDP socket(the default) should never block".

So, now I no longer need a thread for sends
That''s one fewer stitches I need to make and greatly simplifies things. Now it''s just a matter of a thread handling receives on a blocking socket an another thread/s handling everything else.

Just thought the info might be useful before I forget to post it

Webby
> You mention a queue overrun. Do you mean what would happen if say, messages
> were coming into the queue faster than they are being processed?

Just my "better be safe than sorry" approach to engineering problems; don''t take this as an ''you should do this'', but rather a warning about potential problems and some hints about their solutions. As other have stated, you have a particular situation.

If your application sends back a huge load of data for every small incoming request (like a web site), then a sudden increase in the incoming traffic will result in a large send queue. Given the limited bandwidth of the network card, the queue will keep growing if there are no mechanism to keep this under control; you can delay or refuse new incoming requests until all currently pending requests are executed, or limit the ouput buffer to a reasonnable amount. Either way you are protecting the server and the clients already logged in at the price of an apparent lag on new requests; typically those mechanism are rarely triggered, but OTOH debugging a crashed server and making up excuses to angry clients is an ugly option.

-cb
Advertisement
Well there has to be limits somewhere. Either I can limit the number of players that I allow on a server or I can limit the number of packets that get processed. Limiting the number of packets will only come in to play rarely as you mentioned buta robust program should take into account of every possibility it can.

Limiting the number of players on a given server is one of the things I had already planned though I haven''t decided how yet.

I don''t like the Asheron''s Call method where people are kicked out of a zone in the event that too many people arrive because from what I read they kick out the person that has been in the zone the longest time to let the newcomer have a spot. I''m more a fan of "I was here first so I get to stay" rules.

Actual numbers of players per server hasn''t yet come up until now. That question factors game area layout. For this project I am planning a zoned area. Continuous areas are nice for some things but I really don''t think it would work well for what I have planned. One of the things I don''t like about continuous areas is the relative lack of variety one tends to find there. Players aren''t as willing to accept that a forest QUICKLY becomes a desert but they are willing to accept that if I zone out from this location in the forest then I will arrive at this zone in of the desert. Very EQish in this aspect but I think it fits what I am designing more correctly and is easier to create on top of everything else.

The send thread has pretty much been disregarded since sending with UDP doesn''t block. You simply call send with the packet you are sending and the job is done. Whether it gets to the other side or not is another question entirely.

Receiving will still require a queue of some sort as all servers do. For this, there is the idea of having a thread simply for a call to a blocking recieve. If nothing is incoming then it takes up 0 CPU cycles. If something is on the socket then it reads the packet. Since UDP does guarantee that if a packet arrives it will be whole and valid. All I have to do is recieve the packet and store it somewhere for another thread or process to handle. The other thread will check the IP address and packet type and based on that information (and maybe other things) will then pass the packet off to a function for pprocessing.

How the processing gets done is stil undetermined. The server might be sequential in that is first processes ALL packets, then updates game logic, then AI, etc. Or it may be threaded so that one thread handles processing the packets, one thread the AI, etc and all things get updated in simulated parallelism. Pretty much what I''ve described before, only without the thread for sending stuff.

As for the queue. The receiving thread can
A. cast the datastream to the packet type and store that packet onto a main packet queue or
B. simply copy the memory from the recieve call into the main packet queue and let another function deal with casting it to the structure and deciding who gets to handle it.

Once I narrow this down it will be a simple thing to code up various test apps to run some metrics. Easy enough to mimic various types of packets being sent so I will get a general idea of which method would best handle the packets.

Will keep you updated,
Webby
quote:
Original post by WebsiteWill
Just found this helpful and interesting bit of info from "Unix Network Programming" page 398, "...there is no actual UDP socket send buffer. The kernel just copies the application data and moves it down te stack, prepending the UDP and IP headers. Therefore an output operation on a blocking UDP socket(the default) should never block".


Yep. Sorry for the confusion... I actually quoted that same phrase here on gd.net once, it''s a shame how quickly I forget things At least you are going to the de facto authority on network programming... We have several copies of Stevens'' series here at the office, and all are about worn out.

Also, I''m not trying to rail road you into a single threaded application. I''m just trying to help you realise that an increase in threads will most likely NOT result in anything close to a linear increase in performance because of the reasons cited earlier.

Good luck.
Soon as I eat dinner I''m heading over to Barnes and Noble to look up some information on threads and maybe glance through some other networking books to see if anything helps. Mostly out to kill time in a fun way

I realize that just because I make 2 threads that my program won''t run twice as fast. But, if it runs any faster than single (which is has to on a multi processor machine, if programmed correctly) then it''s worth doing.

One thing has to be for certain. EQ and DAoC are running on Unix servers no? And as such they would most certainly not be using select correct? So after that it''s either single threaded non-blocking or some form of threaded servers. I''m willing to bet that they use threads in some manner for this. Not that they are what I am using as a guide. it just seems like the most logical way to go.

Webby
quote:
EQ and DAoC are running on Unix servers no? And as such they would most certainly not be using select correct?

Uh... not exactly. EQ uses a little bit of everything, Sun, Linux and WinNT. EQ uses a couple of different network libraries, one is multithreaded, one isn''t. The MT one has been deprecated throughout the company in favor of a single threaded lib that is used in just about everything except EQ world and zone servers. No, you don''t need select, and you don''t need threads to run an MMO.

For what it''s worth ($0.00) I believe DAoC does indeed use linux servers.
Advertisement
select() is the canonical way of polling multiple sockets on UNIX. You could conceivably set each socket in non-blocking mode and read it to figure out whether there''s any data, but that would require a trip into the kernel for each socket that COULD have data, which is much slower than using a single call to find out which sockets DO have data, and then only tripping into the kernel for those specific sockets.

If you don''t think this distinction matters, you''re not ready to tackle an MMO server, btw :-)
Hmmm. Just returning from Barnes and Noble. Got to thumb through a few books and the only relevant thing I found was in Game Programming Gems 3. In the Networking chapter they mention and tout the use of poll(). Now, is it just me, or is the
poll() function frowned upon? Seems like I''ve seen it degraded on a "Worlds Worst Programming Practices" type of list.

OK, regardless of what EQ or DAoC use, I''m going for the Unix servers for pretty much everything. The only reason that i personally would develop on Windows is because it is undoubetedly the best platform for graphics IMO. It''s also the most widely distributed platform to the end user. I will likely try to support other systems as well but the focus is on Windows. Servers on Linux.

Seems I still have a buttload of researching to do as I reinvent the wheel in this case.

Webby
quote:
Original post by Anonymous Poster
select() is the canonical way of polling multiple sockets on UNIX. You could conceivably set each socket in non-blocking mode and read it to figure out whether there''s any data, but that would require a trip into the kernel for each socket that COULD have data, which is much slower than using a single call to find out which sockets DO have data, and then only tripping into the kernel for those specific sockets.



A couple of comments...
1. We''re talking about a single UDP socket. A non-blocking recvfrom() call when (in an MMO) you will almost always be receiving data, is not introducing any overhead because you will need to call recvfrom anyways to get the data (that most likely will be there).
2. The BSD standard implementation of select() is horrible, and runs through the entire list of descriptors (files, sockets, pipes, all of them) for every single socket in the FDSET. Take a look at the code sometime, it''s laughable. poll() isn''t really too much better.

quote:
If you don''t think this distinction matters, you''re not ready to tackle an MMO server, btw :-)

Interestingly enough the distinction is irrelevant when considering a single socket on a busy server. As far as being ready for an MMO, well it''s not as big a deal as you might think it is...
My personal thoughts on a MMO.
The only differences between MMOs and standard single player games are the networking locig for mass clients, the issue of persistence, requires more game play balancing and finally requires a whole lot more content.

They certainly take longer to create than a standard game but are only more difficult on certain aspects. I''m working on one of those as we speak. I''m not saying that I will make a MMO by any means. I''m very interested in the networking aspect of it. This knowledge would look good on a resume don''t you think? But hey, if I''m not burnt out after making the network module I plan to start the next part. Who knows, maybe in 30 years I''ll have something to play

Webby

This topic is closed to new replies.

Advertisement