多线程的QTcpServer

来源:互联网 发布:dhcp 服务器端口 编辑:程序博客网 时间:2024/06/16 13:30

来自

http://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php


原始代码不再引用,只谈一个有意思的事情。

在多个socket连接中,可以不停的读或者写入,直到socket被断掉。


服务器代码

// myserver.h#ifndef MYSERVER_H#define MYSERVER_H#include <QTcpServer>class MyServer : public QTcpServer{    Q_OBJECTpublic:    explicit MyServer(QObject *parent = 0);    void startServer();signals:    public slots:    protected:    void incomingConnection(qintptr socketDescriptor);     };#endif // MYSERVER_H

// myserver.cpp#include "myserver.h"#include "mythread.h"MyServer::MyServer(QObject *parent) :    QTcpServer(parent){}void MyServer::startServer(){    int port = 1234;    if(!this->listen(QHostAddress::Any, port))    {        qDebug() << "Could not start server";    }    else    {        qDebug() << "Listening to port " << port << "...";    }}// This function is called by QTcpServer when a new connection is available. void MyServer::incomingConnection(qintptr socketDescriptor){    // We have a new connection    qDebug() << socketDescriptor << " Connecting...";        // Every new connection will be run in a newly created thread    MyThread *thread = new MyThread(socketDescriptor, this);        // connect signal/slot    // once a thread is not needed, it will be beleted later    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));        thread->start();}


原始客户端socket连接进入后的处理

// mythread.cpp#include "mythread.h"MyThread::MyThread(qintptr ID, QObject *parent) :    QThread(parent){    this->socketDescriptor = ID;}void MyThread::run(){    // thread starts here    qDebug() << " Thread started";    socket = new QTcpSocket();    // set the ID    if(!socket->setSocketDescriptor(this->socketDescriptor))    {        // something's wrong, we just emit a signal        emit error(socket->error());        return;    }    // connect socket and signal    // note - Qt::DirectConnection is used because it's multithreaded    //        This makes the slot to be invoked immediately, when the signal is emitted.    connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);    connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));    // We'll have multiple clients, we want to know which is which    qDebug() << socketDescriptor << " Client connected";    // make this thread a loop,    // thread will stay alive so that signal/slot to function properly    // not dropped out in the middle when thread dies    exec();}void MyThread::readyRead(){    // get the information    QByteArray Data = socket->readAll();    // will write on server side window    qDebug() << socketDescriptor << " Data in: " << Data;    socket->write(Data);}void MyThread::disconnected(){    qDebug() << socketDescriptor << " Disconnected";    socket->deleteLater();    exit(0);}

对mythread.cpp主要做了两部分修改

1 将这部分使用单独DataClient类,每来一个连接(incommingconnections)

则DataClient * client = new DataClient();

QThread *pt = new QThread();

client->movetoThread(pt);


2 此种情况下则无法在thread中保证exec()循环。在readRead中执行循环。

循环语句类似

            while(1)            {                if(socket->state() == QAbstractSocket::UnconnectedState||                    socket->waitForDisconnected(1000))                 {                    break;                }                qDebug() << "I am client " << socketDescriptor << ", i am working";}




0 0
原创粉丝点击