简体   繁体   中英

Best Practice for Java UDP Multithreading

First off I'd like to apologize for any dumb questions, I'm still learning network programming.

I never did much network programming, other than out of self interest, and I only used Java's Socket and ServerSocket classes. With these classes, the paradigms I used were to have a single Java thread on the server side which accepted connections from clients, and then passed that accepted Socket onto its own Thread. Thus with 100 concurrent clients, there would be (potentially) 100 threads. Then the client and server could talk to each other on their own threads, separate from the other components of the system.

Now enter the DatagramSocket... I'm just learning about TCP vs UDP, so just discovered this class. It makes sense... you listen for packets on a port, and send packets on a port/address. The body contains a certain number of bytes and is optional (Still learning what the max body sizes are and such). From the information online, I've gathered that the socket listens for ANY packets on that port, and derives the source from the packet headers.

This is all good and fine, and I am comfortable with forwarding those packets to their own runnables in a pool, or their own threads, etc. What is bothering me though is that with TCP sockets, each Thread (One of the 100 in the above example) received only messages from the appropriate source. With Datagram sockets, all packets from every client is going to a single thread... and that thread is responsible for divvying the work.

How would something like that work in an MMO game... say you have a game server supporting 5000 players, and each player sends 15 packets per second... That's 75,000 packets per second, which seems heavy for a single thread to handle. (As opposed to 5000 threads which could each have 15 per second). Obviously that one thread could forward the packets to the proper places based on packet headers and a client hashmap, but I'm just uncomfortable that the listener thread itself is doing that logic.

Now it's possible that TCP is doing something similar (Some packet listener thread that forwards the data to the appropriate Socket), so really I'm losing nothing. I guess the root question boils down to... Is it possible to have multiple Server threads listening to the same port? For example, I'm picturing a load balancer which round robins the packets to different DataGramSocket listeners (One on each thread, maybe 3-4 threads). Then those listeners can do the job of the original single thread, which is sending those unordered packets to the correct locations in the program (Example, this packet came from 123.456.789.123 on port 6750... lets check our clientMap for where this should go... Okay, send to that threads packet queue).

I'm guessing the answer is that as long as the thread handling all the client packets is very lightweight (Just receive packet, delegate, repeat), then there is no problem even for high volume traffic.

Thanks!

EDIT: After some thought and Am_I_Helpful's comment (And now Jamal H), I realized you can abstract this out on a machine or port level. So if you have 3000 players, you could have a load balancer of sorts which directs that player to a particular machine or even a particular port on the machine. So that way you could have X number of server threads each listening for packets on a different port. Player 1 may hit port 7712, player 2 may hit 7713.

First of all, if you don't have access to a large team of people, you wouldn't be writing all the network code from scratch for an MMO. You would use some sort of networking framework that handles load balancing and threading for you (Netty is a good one for Java)

For an MMO you would use Non Blocking IO (NIO), which does not map out each client's request to its own thread, but instead has a set number of threads it wants to use (determined by number of cores), and handles it like that

Regarding loading every request on a single thread, there are a couple of options. This is the reason why MMOs have multiple servers, each for a different area in a game. The central server would give the player the IP and port of the area server that he is currently in. You can also have multiple ports accepting on a single server if the server is powerful, and just send different players different ports to send to if you wanted to balance the load across multiple threads

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM