QTcpServer::incomingConnection(qintptr) 没有调用
Posted
技术标签:
【中文标题】QTcpServer::incomingConnection(qintptr) 没有调用【英文标题】:QTcpServer::incomingConnection(qintptr) not calling 【发布时间】:2016-08-22 17:14:43 【问题描述】:我正在尝试使用QTcpSocket 和QTcpServer 制作客户端和服务器。
那么,服务器会发生什么。
-
我运行服务器,它开始监听(成功[我自己检查])
我运行客户端,输入
127.0.0.1
为IP address
和30000
为port
客户说连接已建立
服务器不做任何事情,继续等待
我的部分程序:
//server-work.h
#ifndef SERVERWORK_H
#define SERVERWORK_H
#include <QtCore>
#include <QSqlError>
#include <QDebug>
#include <QSqlQuery>
#include <unistd.h>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtSql/QSqlDatabase>
#include "lssclient.h"
class LSSClient;
class LTcpServer : public QTcpServer
Q_OBJECT
public:
class LTWorkWithClients : public QThread
//Q_OBJECT
public:
LTcpServer* server;
LTWorkWithClients(QObject* parent = 0, LTcpServer *server = 0):
QThread(parent)
this->server = server;
protected:
void run()
qDebug() << "started";
server->workWithIncomingConnection();
;
QSqlDatabase db; // clients in database
LTWorkWithClients* t_workWithClients;
QQueue<quintptr> clientsToBeAttached;
QList<LSSClient*> clients;
LResult workWithIncomingConnection ();
LResult serverInit ();
LResult createDatabase ();
static QTextStream& qStdout ();
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
protected:
private:
;
#endif // SERVERWORK_H
我知道这个嵌套线程类是非常错误的方式来做这件事,但我没有太多时间来正确地做这件事
// server-work.cpp [PART]
LResult LTcpServer::serverInit()
checkError;
db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("serverDB");
if (!db.open())
qDebug() << "Error opening database...";
qDebug() << db.lastError().text();
return LVError;
else
qDebug() << "Database successfully opened";
if(!this->listen(QHostAddress::Any, 30000))
qDebug() << "Error starting listening...";
return LVError;
else
qDebug() << "Start listening successfully";
t_workWithClients = new LTWorkWithClients(this, this);
t_workWithClients->start();
return LVSuccess;
void LTcpServer::incomingConnection(qintptr socketDescriptor)
qDebug() << Q_FUNC_INFO << " new connection";
clientsToBeAttached.enqueue(socketDescriptor);
qDebug() << "here1";
LResult LTcpServer::workWithIncomingConnection()
bool toExit = false;
while (!toExit)
checkError;
qDebug() << "1";
if (clientsToBeAttached.length() != 0)
quintptr eachClientDescriptor = clientsToBeAttached.dequeue();
qDebug() << "2";
LSSClient* client = new LSSClient(this);
client->server = this;
client->socket->setSocketDescriptor(eachClientDescriptor);
qDebug() << "3";
client->registered = false;
client->server = this;
qDebug() << client->socket->localAddress();
connect(client->socket, SIGNAL(readyRead()), client, SLOT(onSokReadyRead()));
connect(client->socket, SIGNAL(connected()), client, SLOT(onSokConnected()));
connect(client->socket, SIGNAL(disconnected()), client, SLOT(onSokDisconnected()));
connect(client->socket, SIGNAL(error(QAbstractSocket::SocketError)),client, SLOT(onSokDisplayError(QAbstractSocket::SocketError)));
clients.append(client);
usleep(1000000);
return LVSuccess;
所以,服务器每秒只写 1(仅此而已),但客户端说它已连接到服务器。
【问题讨论】:
我想说,首先你应该让它在没有任何额外线程的情况下工作。只有当它在主线程中工作时,你应该将对象移动到QThread
(你不需要从QThread
派生)。
我可以看到serverInit
是您创建线程的位置,您没有在此处调用它。
如果你想有一个单独的线程来处理你的连接,你真的做错了。以下是您当前设计的一些问题:1) clientsToBeAttached
、server
在两个线程中使用,没有任何同步机制。 2)您每 1 秒轮询一次以检查队列中是否有任何新连接的客户端。这是生产者/消费者问题的典型示例。看看这是如何在 Qt here 和 here 中完成的。
但您最好阅读Qt Threaded Fortune Example 以避免线程问题。另外,您确定要使用多线程吗?为什么不在你的 GUI 线程中运行所有东西呢?
问题是incomingConnecion 没有触发(没有qdebug 消息)。在我理解为什么incomingConnecion 不触发之前,我看不到线程战斗的感觉......另外,我尝试使用newConnection(没有传递给其他线程),它也没有触发......感谢eз链接,但我已经看过财富例子@Mike
【参考方案1】:
这种结构可能会有所帮助...
在您的 ltcpserver.h 文件中:
class LTcpServer : public QTcpServer
Q_OBJECT
public:
explicit LTcpServer(QObject * parent = 0);
void incomingConnection(qintptr socketDescriptor) Q_DECL_OVERRIDE;
private:
QThread *myThread;
;
在您的 ltcpserver.cpp 中:
LTcpServer::LTcpServer(QObject * parent) : QTcpServer(parent)
if(this->listen(QHostAddress::Any,30000))
qDebug() << "server started...";
else
qDebug() << "server could not be started...";
myThread = new QThread();
myThread->start();
void LTcpServer::incomingConnection(qintptr socketDescriptor)
LSSClient * yourClient = new LSSClient(socketDescriptor);
yourClient->moveToThread(myThread);
clients->append(yourClient);
在你的 lssclient.h 中
class LSSClient: public QObject
Q_OBJECT
public:
explicit LSSClient(qintptr socketDescriptor,QObject * parent = 0);
private:
void setupSocket(qintptr socketDescriptor);
QTcpSocket * socket;
public slots:
void readyRead();
void disconnected();
;
在你的 lssclient.cpp 中
LSSClient::LSSClient(qintptr socketDescriptor,QObject * parent) : QObject(parent)
setupSocket(qintptr socketDescriptor);
void LSSClient::setupSocket(qintptr socketDescriptor)
socket = new QTcpSocket(this);
socket->setSocketDescriptor(sDescriptor);
connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
void LSSClient::readyRead()
// do whatever you want here with incoming data
void LSSClient::disconnected()
// do what happens to client when disconnected
【讨论】:
你测试了吗?传入的Connecion 签名就像我的一样...... 是的...你使用线程不好...更改已在线程中完成 但这对我有帮助吗?.. 这是incomingConnecion 不触发的真正原因吗? 无论如何,我会试试你的结构.. QThread 是什么意思?什么都不做的线程?还是只是举例? 据我了解,您想在另一个线程中与客户打交道(对吗?)以上是关于QTcpServer::incomingConnection(qintptr) 没有调用的主要内容,如果未能解决你的问题,请参考以下文章