【问题标题】:C++ socket server architectureC++ 套接字服务器架构
【发布时间】:2012-08-10 15:43:42
【问题描述】:
我正在为我的实时游戏设计一个 TCP 套接字服务器,我对它的架构提出了两种方法。他们在这里:
我们启动两个线程。一个在无限循环中侦听新连接并将新客户端添加到数组中。第二个顺序扫描数组中的所有客户端套接字并从中读取数据。
我们启动一个线程,它在无限循环中侦听新连接,然后为每个仅从一个套接字读取数据的客户端启动新线程。
我已经对大约 100 个客户端进行了一些测试,但我看不出两种架构的性能差异。所以,我想问问你的意见,哪种方式更好。
谢谢!
【问题讨论】:
标签:
c++
sockets
unix
websocket
serversocket
【解决方案1】:
这完全取决于您的游戏的实际实时性。
在第一种方法中,您将在所有打开的套接字上实现事件的多路分离 - 并且可能使用 select() 或 poll() 来阻止。显然,虽然您只能在阻塞时接收事件通知,并且如果在解除阻塞时传递了多个事件,则您可以有效地序列化每个事件的处理。
在第二种方法中,您可以并行处理事件(尤其是在多处理器系统上),还可以使用线程优先级来确定连接的优先级。但是,这种方法使用更多内存,并且调度线程比第一种方法中的事件列表迭代要昂贵得多。
你需要问自己的问题是:
- 您真的需要并行处理事件吗? (您是否要在处理中序列化执行?)
- 每个事件的处理量是否明显高于调度线程的成本?
- 线程堆栈的内存消耗会限制可扩展性吗?
- 您的实时性要求真的那么严格吗?
【解决方案2】:
在我看来,这取决于你认为什么对你来说更容易。
您使用增强功能吗?如果是,您可以查看他们使用asio 实现此类服务器架构的示例。这样可以避免在监听连接和处理请求时手动管理线程。
还有ZeroMQ,这是一个库,专门用于轻松实现服务器架构。有了它,您可以通过显式控制线程数等来测试更详细的案例。
希望这会有所帮助。
【解决方案4】:
根据经验,我会为新客户设置一个单独的线程,这样您就可以处理登录,并让它等待加入游戏的好时机。我想您并不总是想为新玩家登录而中断游戏。否则,一个主线程可能会变得非常混乱。
您可能还希望线程组中有多个现有游戏线程以实现可扩展性,例如,如果您有 8 个以上的可用内核,则每个游戏一个线程。甚至考虑从新的游戏线程重定向到另一个服务器以获得更大的可扩展性。