简体   繁体   中英

C++ socket server architecture

I'm designing a TCP socket server for my real-time game and I've come to two approaches to it's architecture. Here they are:

  1. We start two threads. One listens for new connections in an indefinite loop and adds new clients to an array. Second sequentially scans all client sockets from the array and reads data from them.

  2. We start one thread, which listens for new connections in an indefinite loop and then starts new thread for each client which reads data just from one socket.

I've made some tests with about 100 clients and I couldn't see difference in performance of both architectures. So, I want to ask your opinion, which way is better. Thank you!

This all rather depends on how real-time your game actually is.

In the first approach, you are implementing the demultiplexing of events on all of the open sockets - and presumably using select() or poll() to block. Clearly, whilst you can only receive notification of an event whilst blocked and you effectively serialise processing of the each event if several are delivered when you unblock.

In the second approach, you have potential to process events in parallel (especially on a multiprocessor system) and also to prioritise connections using thread priority. However, this approach uses more memory, and scheduling threads is considerably more expensive than iterating over a list of events in the first approach.

The questions you need to ask yourself are:

  • Do you actually need to process events in parallel? (are you going to serialise execution in processing anyway?)
  • Is the amount of processing on each event significantly more than the cost of scheduling threads?
  • Will memory consumption for thread stacks limit scalability?
  • Are your real-time requirements really that stringent?

In my opinion, it depends on what you believe is easier for you.

Do you use boost? If yes, you can look through their examples of using asio for implementing such server architectures. This way you can avoid manual management of thread when listening for connections and processing requests.

Also there is ZeroMQ , which is a library, made especially for implementing server architectures easily. With it, you can test even more detailed cases by explicitly controlling numbers of threads, etc.

Hope this helps.

If you want to go WebSocket, here is a quick tip: look at https://github.com/zaphoyd/websocketpp and/or ask the author (Peter). WebSocket++ has a very flexible framework regarding what/how you do your WebSocket processing.

Based on experience I would have a separate thread for the new clients so you can handle the signing in, and have it wait for a good point to join the game. I imagine you don't always want to interrupt a game for new players signing in. The one master thread could get pretty messy otherwise.

You may also want multiple existing game threads in a thread group for scalability, such as one per game if you have 8+ cores available. Consider even redirecting from the new game thread to another server for even larger scalability.

Just use Boost.Asio and be happy! Learn some examples and start making actually game and not a network basics.

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