我試圖使用QTcpSocket和QTcpServer使客戶端和服務器。QTcpServer :: incomingConnection(qintptr)not calling
因此,服務器會發生什麼情況。
- 我運行服務器,它開始偵聽(成功[由我自己檢查])
- 我運行客戶端,輸入
127.0.0.1
爲IP address
和30000
爲port
- 客戶說,連接estabilished
- 服務器沒有按不要做任何事,只要不斷的等待
我的程序的部分:
//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
我知道,這個嵌套Thread類是強烈的錯誤的方式做這件事情,但我沒有太多的時間來正確地做到這一點
// 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'就是你創建線程的地方,你不會在這裏的任何地方調用它。 – Mike
如果你想有一個單獨的線程來處理你的連接,你真的做錯了。這裏有一些與你當前的設計有關的問題:1)'clientsToBeAttached','server'在兩個線程中都使用,沒有任何同步機制。 2)每隔1秒輪詢一次,以檢查隊列中是否有新連接的客戶端。這是生產者/消費者問題的典型例子。看看這是如何在Qt [這裏](http://doc.qt.io/qt-5/qtcore-threads-waitconditions-example.html)和[here](http://doc.qt .IO/QT-5/qtcore線程-旗語-example.html的)。 – Mike