Qt TCP/Ip 网络通信的两种用法-常规用法+多线程用法

  • 常规用法

  1. 创建服务器QTcpServer对象;
  2. 服务器对象开启监听QTcpServer::listen();
  3. QTcpServer::newconnection()信号关联到自定义槽函数;
  4. 槽函数中调用QTcpServer::nextpendingconnection()函数得到客户端连接的QTcpSocket对象;
  5. 使用QTcpSocket对象与客户端通信。
  • 多线程用法

基于多线程的用法有两种,第一种是子类化QThread,重写run函数,在run函数中用while或for语句实现多线程业务;第二种是使用事件循环实现多线程。本文介绍第二种使用方法。

  1. 自定义QObject子类Object处理服务端需要多线程完成的业务,比如网络数据的收发;
  2. 自定义QTcpServer子类TcpServer,子类中重写函数  incomingConnection(qintptr socketDescriptor);
  3. 创建服务器子类TcpServer对象;
  4. 服务器对象开启监听TcpServer::listen();
  5. TcpServer子类的incomingConnection(qintptr socketDescriptor)函数中处理接收到的网络连接信息socketDescriptor,将socketDescriptor参数传递给Object对象,并将QThread对象MoveToThread到Object对象中,到此可以放心的使用信号和槽实现多线程通信;
  6. 在Object类中使用socketDescriptor信息定义QTcpSocket套接字对象;
  7. 使用套接字对象在Object中与客户端通信。

   多线程用法关键代码:

void TcpServer::incomingConnection(qintptr socketDescriptor)
{//多线程网络连接,每个新的网络连接用一个新的线程管理
    QString slog = QString("TcpServer ThreadID::%1").arg(qint64(QThread::currentThreadId()));
    logInfo(slog);

    m_pThread = new QThread;
    m_pObject = new TcpServerObject();
    m_pObject->moveToThread(m_pThread);
    connect(this,SIGNAL(sigInitSocket(qint32)),m_pObject,SLOT(initSocket(qint32)));
    connect(m_pObject,SIGNAL(sigNewTime(QString)),this,SLOT(onNewTime(QString)));
    connect(this,SIGNAL(sigSendData()),m_pObject,SLOT(sendData()));

    m_pThread->start();
    emit sigInitSocket(socketDescriptor);
}

void TcpServerObject::initSocket(qint32 socketDescriptor)
{
    m_pTcpSocket = new QTcpSocket;
    if(!m_pTcpSocket->setSocketDescriptor(socketDescriptor))
    {
        logError(m_pTcpSocket->errorString());
        return;
    }
    connect(m_pTcpSocket,SIGNAL(readyRead()),this,SLOT(recvData()));
}

如下图所示,TcpServer 的ThreadID(即主线程ID:20748)与Object::recvData的 ThreadId、Object::sendData的 ThreadId (即次线程ID:21112)确实不同。因此可以将大量的耗时的业务放在Object类中实现。

注:在基于事件循环的多线程使用方法中,不要在Object的构造函数中作初始化,否则会告警:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值