4

I know similar question to this have been asked, but I haven't found an answer that fixes my problem.

I'm adapting some existing Qt code to add server functionality to a program my company uses. To that end I added a QTcpServer object to the existing dialog, call listen() and connect a slot to the newConnection emitter, like:

    .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() never gets called so I can't see the relevance, but here it is:

   void QConsole::new_Connection()
   {
   }

This works fine in that my program starts listening on the port specified and if I telnet to it a connection of sorts it made, but new_Connection() is never ever ever called!

I've seen posts on this problem dating back to 2005 so it's obviously not a new thing, but what I haven't found is a satisfactory answer to the problem (or any answer actually). This has got everyone at work stumped, even the person that has written a Qt server program. I'm guessing that there is something fundamentally wrong with the existing framework, but I have no idea what it might be.

I have been tearing my hair out for a day and a half over this, and the closes I got to success was using waitForNewConnection() which would actually return me a socket, but when I connected to the readReady() emitter, that was never fired either. So what would prevent these signals never getting called?

Please spare my sanity and help me as much as you can.

Teknogrebo
  • 1,247
  • 1
  • 12
  • 22
  • 1
    That code works just fine here. Please post the new_Connection code, and show how you're calling that `init` method. Adding a minimal `main` to get your code to work minimally would be nice. – Mat Jun 07 '11 at 16:18
  • main code added. There has to be something in my project setup that is preventing the signals being called, but I can't figure it out for the life of me! – Teknogrebo Jun 07 '11 at 16:53
  • how are you determining that the slot is not called? – Mat Jun 07 '11 at 16:56
  • Putting a breakpoint in the new_Connection() function. There is more code, but I deemed it irrelevant considering it's never called. I suppose at this point I should mention that I'm developing this as a Windows app using VS2010. – Teknogrebo Jun 07 '11 at 18:33
  • well, as I said, what you have above WorksForMe (on Linux). Try removing all the extraneous code, keep only what you have there, and put a debug print in the slot. Make sure you're not getting warnings in the console. – Mat Jun 07 '11 at 18:41
  • I had a feeling that it was going to come to that :( I think my next plan of attack will be to create a new barebones project with just the server code in and add in all the functionality from the old project gradually, rather than start with the existing project and add the server code. At least then I'll a very basic example that I can post in full when I can't get that to work either :) – Teknogrebo Jun 07 '11 at 19:00
  • Since you're using VS, running your code in debug mode should tell you when the signal could not be connected. Have a look at the VS debug output. And yes, creating a minimal example to narrow down the sources for mistakes is a good approach. :) – Exa Jun 08 '11 at 06:41
  • Also, are you sure, that m_Server.listen was successfull? You don't check return value at all... – Kamil Klimek Jun 08 '11 at 12:54
  • @Kamil - I know that listen was successful as I have a program that shows me all port activity (can't remember the name as I'm at home). @Exa - I'm running debug build - no errors shown in debug output. It's a complete mystery. Anyway - I've resorted to using another socket library and had much more success. I just wish I knew what particular "gotcha" had got me! – Teknogrebo Jun 08 '11 at 21:37

2 Answers2

3

Here is a complete working example, tested using MSVC++ 2010.

This listens for a connection on port 12346, replies with "HELLO WORLD" and logs the connection to a list on the dialog.

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
Silas Parker
  • 8,017
  • 1
  • 28
  • 43
1

Another working example, again on Linux, although I have coded a program using QTcpServer to run on both Linux and Windows before without a problem. If this doesn't work, surely it must be either a Qt installation or OS configuration problem. Either that or a bug in the Qt version.

~/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
Graeme
  • 2,971
  • 21
  • 26