Qt一步步搭建TcpServer4——Client的封装与网络库的使用

承接上章: Qt一步步搭建TcpServer3——关闭与启动

在上一章讲完Server端的安全启动与关闭之后,我整理了下代码,突然发现内容分配的不太合理,所以这章要说的东西多一点:

封装ClientManager->抽成NetApi静态库项目->在别的项目中使用该NetApi库。

1、创建ClientManager:

ClientManager其实也是类似于Server,自己维护一个会话线程池,客户端要用Session则负责创建一个Session。上层拿到Session之后,再自行封装或者使用,这样做的好处是客户端可以连接多个端,也更方便上层设计:

头文件:

#ifndef CLIENTMANAGER_H
#define CLIENTMANAGER_H
#include "SessionThreads.h"
//客户端Manager
class ClientManager
{
public:
    ClientManager() = default;
    ~ClientManager();

    //启动,默认启动一个线程,非线程安全
    bool Start(uint32_t threadNum = 1);
    //关闭 非线程安全
    void Stop();
    //获取会话数
    std::vector<uint32_t> GetSessionSize() const;
    //创建一个客户端
    std::shared_ptr<TcpSession> CreateClient();

private:
    //线程会话池
    SessionThreads SessionThreads_;
    //是否正在运行
    bool IsRunning_ = false;
};
#endif // CLIENTMANAGER_H

从头文件就能看出来,和Server相比较,还是一样的配方,熟悉的味道。唯一的区别是,Client是负责创建Client的,上层需要一个未连接的Client去连接服务端。而Server需要启动一个监听线程。
cpp:

#include "ClientManager.h"
ClientManager::~ClientManager()
{

}

bool ClientManager::Start(uint32_t threadNum)
{
    if (IsRunning_)
        return false;
    // 验证
    if (threadNum == 0)
        threadNum = std::thread::hardware_concurrency();
    // 启动
    this->SessionThreads_.Start(threadNum);
    IsRunning_ = true;
    return true;
}

void ClientManager::Stop()
{
    if (!IsRunning_)
        return;
    // 停止会话线程池
    this->SessionThreads_.Stop();
    IsRunning_ = false;
}

std::vector<uint32_t> ClientManager::GetSessionSize() const
{
    return this->SessionThreads_.GetSessionSize();
}

std::shared_ptr<TcpSession> ClientManager::CreateClient()
{
    TcpThread *thread = this->SessionThreads_.PickMinThread();
    std::shared_ptr<TcpSession> session = std::make_shared<TcpSession>(thread);
    this->SessionThreads_.AddSession(session);
    session->moveToThread(thread);
    if(thread)
        thread->AddOne();
    return session;
}

这里的代码比较简单,需要简单说明下的是,我将TcpSession和TcpThread等重新整理调整了下。但是整体不影响,所以就直接在最后的代码附件里体现好了,没必要再单独拎出来,都是小改动。

2、封装成静态库:

2.1、 新建NetApi的静态库项目:

这里写图片描述
并且把之前写的那些文件添加到该项目中(如图)。

2.2、命名空间:

既然都封装成lib库了,那不妨再为我们的NetApi取个命名空间吧,这样用起来也更方便,更模块化。
在NetApi项目中新建头文件:
NetApiNameSpace.h:

#ifndef NETAPINAMESPACE_H
#define NETAPINAMESPACE_H
//命名空间
#ifndef NETAPI_NAMESPACE_BEGIN
#define NETAPI_NAMESPACE_BEGIN  namespace NetAPI {
   
#define NETAPI_NAMESPACE_END }
#endif

#endif // NETAPINAMESPACE_H

这里用的是两个宏定义,这样在类中可以直接用宏就行了。
比如:
TcpThread:

#ifndef TCPTHREAD_H
#define TCPTHREAD_H
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值