您的位置:首页 > 理论基础 > 计算机网络

多线程的QTcpServer

2015-07-20 09:03 609 查看
来自
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";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: