Я просто не могу заставить работать QTcpServer (newConnection никогда не вызывается)
Я знаю, подобный вопрос был задан, но я не нашел ответа, который решает мою проблему.
Я адаптирую существующий код Qt, чтобы добавить функциональность сервера в программу, которую использует моя компания. Для этого я добавил объект QTcpServer в существующее диалоговое окно, вызвал listen() и подключил слот к источнику newConnection, например:
.h
class QConsole : public QDialog
{
Q_OBJECT
public:
void init();
public slots:
void new_Connection();
private:
QTcpServer m_Server;
}
.cpp
void QConsole::init()
{
m_Server.listen(QHostAddress::Any, 12346);
QDialog::connect(&m_Server, SIGNAL(newConnection()), this, SLOT(new_Connection()));
}
Основным является:
int main( int argc, char *argv[] )
{
QApplication app(argc, argv);
QConsole * _output_window = new QConsole(desktopRect);
_output_window->init();
_output_window->show();
return app.exec();
}
new_Connection() никогда не вызывается, поэтому я не вижу релевантности, но вот оно:
void QConsole::new_Connection()
{
}
Это прекрасно работает, так как моя программа начинает прослушивать указанный порт, и если я подключаюсь к нему через какое-то соединение, которое она установила, но new_Connection() никогда не вызывается!
Я видел сообщения по этой проблеме, начиная с 2005 года, так что это, очевидно, не новая вещь, но то, что я не нашел, - это удовлетворительный ответ на проблему (или любой ответ на самом деле). Это ставит всех в тупик, даже человека, написавшего программу на Qt-сервере. Я предполагаю, что с существующей структурой что-то не так, но я понятия не имею, что это может быть.
Я рвал свои волосы в течение полутора дней из-за этого, и закрытие, которое я добился успеха, использовало waitForNewConnection(), которое фактически возвращало бы мне сокет, но когда я подключался к источнику readReady(), это никогда не было уволен либо. Так что же помешало бы никогда не вызывать эти сигналы?
Пожалуйста, пощади мое здравомыслие и помоги мне как можно больше.
2 ответа
Вот полный рабочий пример, протестированный с использованием MSVC++ 2010.
Он прослушивает соединение через порт 12346, отвечает "HELLO WORLD" и записывает соединение в список в диалоговом окне.
main.cpp
#include <QtGui>
#include "console.hpp"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
Console con;
con.show();
return app.exec();
}
console.hpp
#include <QtCore>
#include <QtGui>
#include <QtNetwork>
class Console : public QDialog
{
Q_OBJECT
public:
Console();
public slots:
void connection();
private:
QTcpServer mServer;
QListWidget* mConnList;
};
console.cpp
#include "console.hpp"
Console::Console() :
QDialog(),
mServer(),
mConnList(new QListWidget())
{
if (!mServer.listen(QHostAddress::Any, 12346))
qDebug() << "Error during 'listen'" << mServer.errorString();
connect(&mServer, SIGNAL(newConnection()), this, SLOT(connection()));
QVBoxLayout* mainLayout = new QVBoxLayout();
mainLayout->addWidget(mConnList);
setLayout(mainLayout);
}
void Console::connection()
{
qDebug() << "CONNECTION";
QTcpSocket* skt = mServer.nextPendingConnection();
if (!skt)
return;
mConnList->addItem(QString("%1:%2").arg(skt->peerAddress().toString()).arg(skt->peerPort()));
skt->write("HELLO WORLD!\r\n");
skt->close();
}
test.pro
TEMPLATE=app
CONFIG+=console debug
QT=core gui network
HEADERS=console.hpp
SOURCES=main.cpp console.cpp
Еще один рабочий пример, опять-таки о Linux, хотя я ранее без проблем написал программу, использующую QTcpServer для работы на Linux и Windows. Если это не сработает, это может быть проблема установки Qt или конфигурации ОС. Либо это, либо ошибка в версии Qt.
~/tcp_test$ qmake --version
QMake version 2.01a
Using Qt version 4.8.6 in /usr/lib/x86_64-linux-gnu
~/tcp_test$ for file in qconsole.{h,cpp} main.cpp tcp_test.pro ; do echo -e "$file:\n"; cat $file; echo; echo; done
qconsole.h:
#include <QDialog>
#include <QTcpServer>
class QConsole : public QDialog
{
Q_OBJECT
public:
QConsole();
public slots:
void connection();
private:
QTcpServer server;
};
qconsole.cpp:
#include "qconsole.h"
QConsole::QConsole()
{
server.listen(QHostAddress::Any, 12346);
QDialog::connect(&server, SIGNAL(newConnection()), this, SLOT(connection()));
}
void QConsole::connection()
{
qDebug("got connection");
}
main.cpp:
#include <QApplication>
#include "qconsole.h"
int main( int argc, char *argv[] )
{
QApplication app(argc, argv);
QConsole * window = new QConsole();
window->show();
return app.exec();
}
tcp_test.pro:
QT = core gui network
CONFIG += debug
TARGET = tcp_test
SOURCES = main.cpp qconsole.cpp
HEADERS = qconsole.h
~/tcp_test$ ./tcp_test &
[3] 9784
~/tcp_test$ nc localhost 12346
got connection
^C