Qtcpserver question



  • hi

    my programm launches an qtcpipserver and this one starts a tcpsocket when a client is there to connect.

    the programm crashes at the line, where i want to connect the "connected" signal to a checkbox of the ui.

    here the 3 relevant files to reproduce it.

    tcpserver.h
    @#ifndef TCPSERVER_H
    #define TCPSERVER_H

    #include <QObject>
    #include <QtDebug>
    #include <QTcpSocket>
    #include <QTcpServer>

    class tcpserver : public QObject
    {
    Q_OBJECT
    public:

    explicit tcpserver(QObject *parent = 0);
    
    QTcpServer *server;
    QTcpSocket *socket;
    

    signals:

    public slots:
    void newconnection();
    void m_auto();
    };

    #endif // TCPSERVER_H
    @

    tcpserver.cpp
    #include "tcpserver.h"
    @
    tcpserver::tcpserver(QObject *parent) :
    QObject(parent)
    {
    server = new QTcpServer (this);
    connect (server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }

    void tcpserver::newconnection()
    {
    QTcpSocket *socket = server->nextPendingConnection();
    // socket->write("hello client");
    // socket->flush();
    // socket->waitForBytesWritten(3000);
    // socket->close;
    }

    void tcpserver::m_auto()
    {
    // socket->write("m_auto=1");
    // socket->flush();
    // socket->waitForBytesWritten(3000);
    }@

    main.cpp
    @#include <QtGui/QApplication>
    #include "robbie20.h"
    #include "tcpconnect.h"
    #include "tcpserver.h"
    #include <QObject>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);

    Robbie20 w;
    w.show();
    

    // w.loadTextFile();
    tcpserver server;
    // server.newconnection();

    tcpconnect client;
    
    QObject::connect(server.socket,SIGNAL(connected()), &w, SLOT(chkbox_server()));
    QObject::connect(server.socket,SIGNAL(disconnected()), &w, SLOT(chkbox_server_un()));
    

    ...
    return a.exec();
    }@

    if one of those 2 last files is compiled, and i run the program it crashes with the -1073741819
    error

    any ideas what i made wrong?
    thanks in advance

    rafael

    [[Merged two identical threads as requested, Tobias]]



  • ok here is the
    robbie20.cpp

    @#include "robbie20.h"
    #include "ui_robbie20.h"

    Robbie20::Robbie20(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Robbie20)
    {
    ui->setupUi(this);
    }

    Robbie20::~Robbie20()
    {
    delete ui;
    }

    void Robbie20::loadTextFile()
    {
    QDate date = QDate::currentDate();
    QString datum = date.toString("yyyyMMdd");
    QFile inputFile("c://LOGS/" + datum + ".log");
    inputFile.open(QIODevice::ReadOnly);

    QTextStream in(&inputFile);
    QString line = in.readAll();
    inputFile.close();
    
    ui->textBrowser->setPlainText(line);
    QTextCursor cursor = ui->textBrowser->textCursor();
    cursor.movePosition(QTextCursor::End);
    ui->textBrowser->setTextCursor(cursor);
    

    }

    void Robbie20::chkbox_client()
    {
    ui->checkBox_2->setEnabled(1);
    ui->checkBox_2->setChecked(1);
    ui->checkBox_2->setEnabled(0);
    }

    void Robbie20::chkbox_client_un()
    {
    ui->checkBox_2->setEnabled(1);
    ui->checkBox_2->setChecked(0);
    ui->checkBox_2->setEnabled(0);
    }

    void Robbie20::chkbox_server()
    {
    ui->checkBox->setEnabled(1);
    ui->checkBox->setChecked(1);
    ui->checkBox->setEnabled(0);
    }

    void Robbie20::chkbox_server_un()
    {
    ui->checkBox->setEnabled(1);
    ui->checkBox->setChecked(0);
    ui->checkBox->setEnabled(0);
    }@



  • hi,

    i launch an tcpserver which listen on port 555.

    @
    #include "tcpserver.h"

    tcpserver::tcpserver(QObject *parent) :
    QObject(parent)
    {
    server = new QTcpServer (this);
    connect (server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }

    void tcpserver::newconnection()
    {
    QTcpSocket *socket = server->nextPendingConnection();
    // socket->write("hello client");
    // socket->flush();
    // socket->waitForBytesWritten(3000);
    // socket->close;
    }
    @

    after tcpserver is initialisated, the newconnection methode will be run when a client is there.

    how can i connect to the connected-signal from this socket in main.cpp

    s.th. like this?
    @QObject::connect(w.server.socket,SIGNAL(connected()), &w,SLOT(check_checkbox()));@

    i dont know with the pointers to acces the socket from here.

    s.o. knows how to do it?



  • i tried

    QObject::connect(w.server->nextPendingConnection(),SIGNAL(connected()), &w, SLOT(check_checkbox()))

    it crashes with -1073741819 error.



  • the debugger tells me its a segmentation fault error


  • Moderators

    [quote author="roboterprogrammer" date="1338814874"]
    @
    void tcpserver::newconnection()
    {
    QTcpSocket *socket = server->nextPendingConnection();
    // socket->write("hello client");
    // socket->flush();
    // socket->waitForBytesWritten(3000);
    // socket->close;
    }
    @
    [/quote]

    If this part is still as shown above, that is as least part of the cause of your trouble. You create a local copy of the pointer. How do you plan to use it afterwards when the method ended?

    You need to save the copy of a socket in class declaration. Then you can also make a connect to the signals of the socket.



  • hi,

    thanks, i tried it but still same error:
    from header file
    @public:
    explicit test11(QWidget *parent = 0);
    ~test11();
    void connecte();
    QTcpSocket *sockete;
    QTcpServer *server;
    QTcpSocket *socke;
    QTcpSocket m_socke;@

    the two methodes:

    @void test11::tcpserver()
    {
    server = new QTcpServer (this);
    connect(server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }

    void test11::newconnection()
    {
    QTcpSocket *socke = server->nextPendingConnection();
    m_socket = socke;
    // socke = new QTcpServer (this);
    // socke = server->nextPendingConnection();
    }@

    and the syntax in main.cpp
    @ QObject::connect(&w.m_socke,SIGNAL(connected()), &w, SLOT(check_checkbox3()));@

    how did u mean it?


  • Moderators

    Try this:

    @public:
    explicit test11(QWidget *parent = 0);
    ~test11();
    void connecte();
    QTcpSocket *sockete;
    QTcpServer *server;
    QTcpSocket *socke;
    //QTcpSocket m_socke;
    @

    @void test11::newconnection()
    {
    socke = server->nextPendingConnection();
    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    if ( !boo)
    {
    // you might introduce some error handling
    }

    }@

    NOTE: not checked brain to keyboard :-) I have assumed that "socke" is meant for this. If it is used otherwise you need to substitude.



  • the tcpserver member QTcpSocket *socket is never initialized (and thus a dangling pointer you try to access when connecting to it).

    I suspect you want this line
    @
    QTcpSocket *socket = server->nextPendingConnection();
    @
    to initialize the socket, but all you do is create a pointer "socket" on the stack which hides the classes pointer with the same name.

    But even if you initialize it correctly by removing the "QTcpSocket" from the front, you still try to connect in main() to this pointer without the guarantee that newconnection() was already called.
    You should set up the connections when socket becomes valid, i.e. in newconnection(). Better yet, create signals on your object so you don't have to access socket from the outside. All your checkbox (and the outer code) sees, is the public signal/slot interface of your tcpserver object. All internals, i.e. the forwarding of the socket signal to the respective tcpserver signal, should be done internally in tcpserver.



  • hi thanks to you two!

    ok now i have it like this in the method
    @*socket = server->nextPendingConnection();@

    but the checkbox will not get checked.

    i can see that the connection is there
    @ if (sockete->ConnectedState == 0)
    {
    qDebug() << "0-server";
    }
    if (sockete->ConnectedState == 3)
    {
    qDebug() << "3-server";
    }@

    i tried to make it in the class itself like koahnig described, but it just leaves the box empty.

    when i try to connect to it in the main.cpp it crashes.

    BTW @dermanu: i know its not the best programming style to make thoses connections in main.cpp and not in the class direct.
    this is my 1st qt-project, and i wasn't OO-Programming.

    so for understanding how to jump with variables between classes, its good to see how to operate it.

    for future projects i will do it like this, everything most encapsulated.

    so now, as socke is a public accessible variable,
    how can i use it in main.cpp without a crash?

    as pointer with & i get compiling error,

    f.x. from main.cpp
    w.socke->write ("hello client");

    crashes with same error

    please continue support.
    one quick offtopic question:
    when i want to programm objectoriented qt, and i have 3 classes, lets say one project.cpp (with the ui and...), one writefile.cpp and one network.cpp

    and i want to have a qObject::connect relation between writefile.cpp and network.cpp methods.
    where do i link them?
    in main.cpp or directly in writefile.cpp by including the others headerfile?

    thanks


  • Moderators

    Sorry, IMO the merging of threads mixed it completely. The timeline is broken and there is no way to get an overview in what state your code is. The socket on the server side may be "socke", "socket" and "sockete" depending on which thread is looked at. IMO the naming might be the origin of your problem.

    My suggestion is cleaning out your code. Remove stuff you do not need at the moment. Either you find the problem then already or you need to post the new, cleaned sources again.



  • hi koahnig

    y, sockete is for the tcpip-client
    socke is for the tcpip-server

    the programm connects as client, and also makes server.

    you are right, i c&p the tcpip-client one, without changing it to the server:
    @
    if (socke->ConnectedState == 0)
    {
    qDebug() << "0-server";
    }
    if (socke->ConnectedState == 3)
    {
    qDebug() << "3-server";@

    thats the code which showes me that the connection works.



  • @void test11::tcpserver()
    {
    server = new QTcpServer (this);
    connect(server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }@

    @
    void test11::newconnection()
    {
    // connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    socke = server->nextPendingConnection();
    // socke = new QTcpServer (this);
    // socke = server->nextPendingConnection();

    connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));

    if (socke->ConnectedState == 0)
    {
        qDebug() << "0-server";
    }
    if (socke->ConnectedState == 3)
    {
        qDebug() << "3-server";
    }
    

    }@

    thats the code where it just doesn't work -> no checkbox is set.
    or is it more s.th. with pointers and adresses?
    socke* = &server->nextPendingConnection();
    instead of copying it?


  • Moderators

    [quote author="roboterprogrammer" date="1338889243"]@void test11::tcpserver()
    {
    server = new QTcpServer (this);
    connect(server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }@

    @
    void test11::newconnection()
    {
    // connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    socke = server->nextPendingConnection();
    // socke = new QTcpServer (this);
    // socke = server->nextPendingConnection();

    connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));

    if (socke->ConnectedState == 0)
    {
        qDebug() << "0-server";
    }
    if (socke->ConnectedState == 3)
    {
        qDebug() << "3-server";
    }
    

    }@
    [/quote]
    That should be fine.

    [quote author="roboterprogrammer" date="1338889243"]
    or is it more s.th. with pointers and adresses?
    socke* = &server->nextPendingConnection();
    instead of copying it?[/quote]
    No. Definitely not.

    You may want to check out the "documentation of nextPendingConnection":http://qt-project.org/doc/qt-4.8/qtcpserver.html#nextPendingConnection
    [quote] The socket is created as a child of the server, which means that it is automatically deleted when the QTcpServer object is destroyed. [/quote]
    So you need to make sure that QTcpServer object is still living.

    You should check the return code of connect. This is certainly a point to find out when the connect did not work. This solves most of the time mysteries already. You can do similar as shown here in my previous post:
    [quote author="koahnig" date="1338823176"]
    @void test11::newconnection()
    {
    socke = server->nextPendingConnection();
    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    if ( !boo)
    {
    // you might introduce some error handling
    }

    }@
    [/quote]

    Most people are not using this return value, but it provides some heads up ;-)



  • Another option is to use assert (e.g. "Boost.StaticAssert":http://www.boost.org/doc/libs/1_49_0/doc/html/boost_staticassert.html or "cassert":http://www.cplusplus.com/reference/clibrary/cassert/assert/) in connection with the return value of the connect() calls that should always return true. This way you will immediately know if you did something wrong.

    @
    #ifdef _DEBUG
    BOOST_STATIC_ASSERT(connect(....));
    // or
    bool test = connect(..);
    BOOST_STATIC_ASSERT(test);
    #endif
    @


  • Moderators

    [quote author="KA51O" date="1338900997"]Another option is to use assert (e.g. "Boost.StaticAssert":http://www.boost.org/doc/libs/1_49_0/doc/html/boost_staticassert.html or "cassert":http://www.cplusplus.com/reference/clibrary/cassert/assert/) in connection with the return value of the connect() calls that should always return true. This way you will immediately know if you did something wrong.

    @
    #ifdef _DEBUG
    BOOST_STATIC_ASSERT(connect(....));
    // or
    bool test = connect(..);
    BOOST_STATIC_ASSERT(test);
    #endif
    @
    [/quote]

    You are certainly correct with your suggestion. I did not propose "assert", yet, because it may provide a stumble stone if not used properly.

    Your example code is showing by accident also the problem. Doing the connect within ifdefs, as above, will create a problem when compiled in release mode. If _DEBUG is not defined, the connect will not be compiled and never executed.

    A similar problem will occur when using assert inproperly:
    @
    #include <cassert>
    ...
    assert ( connect ( ... ) ); // this is a nogo as well, because assert will not be included in release modes
    @

    When using assert, it should be in this way:
    @
    #include <cassert>
    ...
    bool boo = connect ( ... ); // this will work in debug and release
    assert ( boo );
    @
    The only back draw will be sometimes that the compiler is complaining about unused variable boo in release mode.



  • @void test11::newconnection()
    {
    // connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    socke = server->nextPendingConnection();
    // socke = new QTcpServer (this);
    // socke = server->nextPendingConnection();

    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(ui->checkBox_3->setChecked(1);));
    if (boo)
    {
    qDebug() << "boo = 1";
    // ui->checkBox_3->setChecked(1);
    }
    else
    qDebug() << "boo = 0";

    if (socke->ConnectedState == 0)
    {
        qDebug() << "0-server";
    }
    if (socke->ConnectedState == 3)
    {
        qDebug() << "3-server";
    }
    

    }@

    hi thank you both for the hinds.
    i will try only to use the functions included in native qt, because it will be used in industry as gui for robot and we only buy a qt-licence. if using boost, we may have to buy more...

    back to the topic:

    the bool is 1.
    but it doesnt make the check.
    the uncommented line in
    @ {
    qDebug() << "boo = 1";
    ui->checkBox_3->setChecked(1);
    }@

    or

    @ {
    qDebug() << "boo = 1";
    check_checkbox3();
    }@
    works.

    so it gets 1, its in the main class, everything looks good.
    why doesn't it work?

    thanks a lot

    here one more time everything:

    test11.cpp
    @#include "test11.h"
    #include "ui_test11.h"

    test11::test11(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::test11)
    {
    ui->setupUi(this);
    }

    test11::~test11()
    {
    delete ui;
    }

    void test11::tcpserver()
    {
    server = new QTcpServer (this);
    connect(server,SIGNAL(newConnection()),this,SLOT(newconnection()));
    server->listen(QHostAddress::Any,555);
    }

    void test11::newconnection()
    {
    // connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    socke = server->nextPendingConnection();
    // socke = new QTcpServer (this);
    // socke = server->nextPendingConnection();

    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    if (boo)
    {
    qDebug() << "boo = 1";
    check_checkbox3();
    }
    else
    qDebug() << "boo = 0";

    if (socke->ConnectedState == 0)
    {
        qDebug() << "0-server";
    }
    if (socke->ConnectedState == 3)
    {
        qDebug() << "3-server";
    }
    

    }

    void test11::connecte()
    {
    sockete = new QTcpSocket(this);
    sockete->connectToHost("192.168.2.10",2000);
    qDebug() << "Verbinde mit Robotersteuerung ....";

    if (sockete->ConnectedState == 0)
    {
        qDebug() << "0";
    }
    if (sockete->ConnectedState == 3)
    {
        qDebug() << "3";
    }
    

    }

    void test11::on_pushButton_clicked()
    {
    if( ui->checkBox->isChecked())
    {
    ui->checkBox->setEnabled(1);
    ui->checkBox->setChecked(0);
    ui->checkBox->setEnabled(0);
    qDebug() << "is checked = 0";
    }
    else
    {
    ui->checkBox->setEnabled(1);
    ui->checkBox->setChecked(1);
    ui->checkBox->setEnabled(0);
    qDebug()<< "is checked = 1" ;
    }

    }

    void test11::on_pushButton_2_clicked()
    {

    }

    void test11::check_checkbox()
    {
    ui->checkBox_2->setChecked(1);
    }

    void test11::uncheck_checkbox()
    {
    ui->checkBox_2->setChecked(0);
    }

    void test11::check_checkbox3()
    {
    ui->checkBox_3->setChecked(1);
    }

    void test11::uncheck_checkbox3()
    {
    ui->checkBox_3->setChecked(0);
    }

    @

    main.cpp
    @#include <QtGui/QApplication>
    #include "test11.h"

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    test11 w;
    w.show();
    w.connecte();
    w.tcpserver();
    QObject::connect(w.sockete,SIGNAL(connected()), &w,SLOT(check_checkbox()));
    QObject::connect(w.sockete,SIGNAL(disconnected()), &w,SLOT(uncheck_checkbox()));
    // QObject::connect(w.socke,SIGNAL(disconnected()), &w,SLOT(uncheck_checkbox3()));
    //&w.socke->write("helo");
    // socket->flush();
    // socket->waitForBytesWritten(3000);
    // socket->close;
    return a.exec();
    }
    @

    and
    test11.h
    @#ifndef TEST11_H
    #define TEST11_H

    #include <QMainWindow>
    #include <QDebug>
    #include <QObject>
    #include <QTcpSocket>
    #include <QAbstractSocket>
    #include <QtGui/QApplication>
    #include <QTcpServer>
    #include <QLocalSocket>

    namespace Ui {
    class test11;
    }

    class test11 : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit test11(QWidget *parent = 0);
    ~test11();
    void connecte();
    QTcpSocket *sockete;
    QTcpServer *server;
    QTcpSocket *socke;
    QTcpSocket m_socke;

    private slots:

    public slots:
    void on_pushButton_clicked();
    void check_checkbox();
    void on_pushButton_2_clicked();
    void uncheck_checkbox();
    void check_checkbox3();
    void uncheck_checkbox3();

    void newconnection();
    void tcpserver();
    

    private:
    Ui::test11 *ui;
    };

    #endif // TEST11_H
    @



  • This is just wrong:
    @
    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(ui->checkBox_3->setChecked(1);));
    @
    If this really is the code your using you must be getting boo = 0 in qDebug.

    later you are using a correct version
    @
    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    @
    before doing the connect(..) test if the returned socket is not NULL, maybe that's your problem.

    Another idea is that the connected() signal of the socket is already emitted before you connect to it, since you retrieve the socket from the server after the server has established the connection. Maybe you can test the sockets state before doing the connect.
    @
    if(socke != NULL)
    {
    if(socke->state() == QAbstractSocket::ConnectedState)
    {
    //socket is already connected
    check_checkbox3();
    }
    else
    bool boo = connect(socke,SIGNAL(connected()), this, SLOT(check_checkbox3()));
    }
    else
    {
    //something went wrong
    }
    @


  • Moderators

    Concerning your doubts of licensing. assert is part of the standard and supplied with the compiler.
    Check out "boost":http://www.boost.org/ is states:
    [quote]The Boost license encourages both commercial and non-commercial use. [/quote]
    The licensing is not homogeneous, but in most cases there should be no problem.
    There is even a Qt version of assert, but I never used.

    Concerning your actual problem, you should place break points in the debugger where ever you think it is important. That way you can even follow into routines and methods. In your case you may want to put a break point onto the check statement in question. Personally I find it more convenient than debug statements.

    The problem I see currently is the way you are setting the check state. You should use the supplied macros for "checkState":http://qt-project.org/doc/qt-4.8/qt.html#CheckState-enum

    I just saw that this is "tristate bool for QCheckBox":http://qt-project.org/doc/qt-4.8/qcheckbox.html and 1 does not mean checked anymore. But that may be dependent on the version you are using. When using the predefined values you avoid such traps.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.