多连接客户端套接字应用程序C ++

时间:2017-11-08 00:36:36

标签: c++ linux sockets winapi

我正在开发一个连接到不同服务器的应用程序,收集数据并显示它。 实际上,我已经创建了它,但感觉我错了,因为它创建了一堆线程,我确实知道它不可扩展。

现在我有以下逻辑(简化的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指南的各种问题(在2000,XP,Vista上没有几个winsock功能)。

我读到了asio,libev实现,但是他们隐藏了细节,最终我缺乏知识正是让我陷入这种境地的原因。 现在我只是迭代并更新所有活动连接,收集数据和显示,但我总觉得这不是一个正确的实现。

1 个答案:

答案 0 :(得分:0)

你可以通过两个线程来实现,一个是UI线程,一个是网络线程,在网络线程中,你可以使用asio或libev。数据可以通过队列或共享变量传递。并使用条件变量或互斥来同步线程。你可以参考pthread库和man select函数。