多线程的QTcpServer

来自

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_OBJECT
public:
    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";
}




你可能感兴趣的:(多线程的QTcpServer)