多连接客户端套接字应用程序 C++
Posted
技术标签:
【中文标题】多连接客户端套接字应用程序 C++【英文标题】:multi-connection client socket application C++ 【发布时间】:2017-11-08 00:36:36 【问题描述】:我正在开发一个连接到不同服务器、收集数据并显示它的应用程序。 实际上,我已经创建了它,但感觉我把它弄错了,因为它创建了一堆线程,而且我明白它是不可扩展的。
现在我有以下逻辑(简化的 c++ 伪代码):
// handles one connection
class Client
public:
void start(); //opens socket, connects, starts threads
void stop(); //closes socket, joins threads
ClientState getState();
void requestState();
private:
thread _threadReceive; // runs "handleReceive()" in a loop
thread _threadSend; // runs "handleSend()" in a loop
thread _threadUpdate; // runs "update()" in a loop
queue _commands;
queue _replies;
ClientState _currentState;
void handleReceive(); // recv reply from server, push to "_replies"
void handleSend(); // pops from "_commands", send to server
void update(); // pops reply, processes it, updates current state
//...
;
然后我有以下内容:
//App's logic
class App
public:
void start(); // init app, creates clients from config
void stop(); // iterates over "_clients" and calls "stop()", joins threads
private:
vector<Client> _clients;
vector<ClientState> _clientStates;
thread _threadUpdateClients;
thread _threadRequestClients;
void connect(); //iterate over "_clients" and "start()";
void updateStates(); //iterate over "_clients" and fill "_clientStates" accordingly
void requestStates(); //iterate over "_clients" and call "requestState()"
void updateUi(); // iterate over "_clientStates" and display them
//...
显然,这意味着要使用大量锁定和各种丑陋的代码来同步所有内容(这会导致上下文切换)。最令人沮丧的部分是它可以工作并且在成功的应用程序中成长。
此代码是我几年前编写的 .NET 4.5 C# 代码(这是我的第一个实际多线程应用程序)的直接移植 - 我需要在几台 Windows 2000 和 XP SP1 机器上执行它。 我“感觉到”了所有问题,但我不知道如何以适当的方式实施它。有很多简单的客户端-服务器教程,但我从来没有发现任何关于模式/架构、程序结构的东西。我也阅读了很多关于 select() 和非阻塞套接字的内容,但我真的很困惑:
如何正确使用select()? 如何使用非阻塞套接字组织状态/数据存储、队列等。 它在 Windows XP 上是否可用,因为我在使用 MSDN 指南时遇到了各种问题(一些 winsock 功能在 2000、XP、Vista 上不可用)。我阅读了有关 asio、libev 实现的信息,但它们隐藏了细节,最终我缺乏知识正是导致我陷入这种情况的原因。 现在我只是简单地迭代和更新所有活动的连接,收集数据并显示,但我总觉得这不是一个正确的实现。
【问题讨论】:
互联网上有 吨 的网络教程,其中许多包括使用 Windows 套接字 API(这与“标准”POSIX API)。最好的当然包括如何使用select
。
此外,虽然您绝对应该了解套接字和网络如何在较低级别上工作,但一旦您学会了废弃代码并转向更高级别的 API 或框架。从长远来看,使用高级框架了解幕后发生的事情是一件好事(而且 IMO 是强制性的)可以让程序员的生活变得更加轻松。
这个问题跑题了。询问架构的更好地方是Software Engineering。
@IInspectable 在引用其他网站时,指出cross-posting is frowned upon 通常会有所帮助
【参考方案1】:
你可以使用两个线程,一个是UI线程,一个是网络线程,在网络线程中,你可以使用asio或libev。数据可以通过队列或共享变量传递。并使用条件变量或互斥锁来同步线程。可以参考 pthread 库和 man select 函数。
【讨论】:
以上是关于多连接客户端套接字应用程序 C++的主要内容,如果未能解决你的问题,请参考以下文章
c++ 服务器在客户端终止连接进程后不关闭 TCP 套接字连接
C++ UNIX 帮助 - 简单的 TCP 服务器套接字连接