Я просто не могу заставить работать QTcpServer (newConnection никогда не вызывается) - PullRequest
4 голосов
/ 07 июня 2011

Я знаю, что был задан похожий вопрос, но я не нашел ответа, который решает мою проблему.

Я адаптирую некоторый существующий код 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()));
    }

Main is:

    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 ]

3 голосов
/ 30 сентября 2013

Вот полный рабочий пример, протестированный с использованием 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
1 голос
/ 30 сентября 2013

Еще один рабочий пример, опять же для 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
...