Tcpsocket newbie



  • Hey everyone, I'm working on an app that should receive 10 integer data values over a tcp connection.
    I've never dealt with networking and was looking to send a single value of a horizontal slider over the network for testing purposes.
    My current code is:

    #include "singleslider.h"
    #include "ui_singleslider.h"
    
    singleslider::singleslider(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::singleslider)
    {
        socket = new QTcpSocket(this);
        ui->setupUi(this);
        server = new QTcpServer(this);
    
        if(!server->listen(QHostAddress::Any,1234))
        {
            qDebug()<< "not started";
        }
        else
        {
            qDebug() << "Server Started";
        socket = server->nextPendingConnection();
        }
    
    
    }
    
    singleslider::~singleslider()
    {
        delete ui;
    }
    
    void singleslider::on_horizontalSlider_valueChanged(int value)
    {
       socket->write("3");
       socket->flush();
    }
    
    

    I was having difficulty sending the actual value so I tried to trivialize the problem to sending a single value "3". Unfortunately, even this code causes the application to crash upon moving the horizontal slider.

    Anyone have any advice. Thanks.

    For more context, the client side code is as follows:
    
    ```
    void MainWindow::Connect()
    {
        socket = new QTcpSocket(this);
    
        connect(socket, SIGNAL(readyRead()), this, SLOT(changeSomething()));
    
        socket->connectToHost("10.121.124.218", 1234);
    
        if(socket->waitForConnected(3000))
        {
            qDebug() << "Connected";
        }
        else
        {
            qDebug() << "Not Connected";
        }
    }
    
    void MainWindow::changeSomething()
    {
        qDebug() << "Socket as something to read";
        while(socket->bytesAvailable() > 0)
        {
            //Test to see if socket is reading
            socket->readAll();
            rpm1_needle->setCurrentValue(5);
        }
    }
    ```

  • Qt Champions 2016

    Hi and welcome
    Nothing really shouted "crash!" looking at you code.
    so when it calls ( because u touch the slider)

    
    void singleslider::on_horizontalSlider_valueChanged(int value)
      >>> socket->write("3"); <<< it crashes here?
    

    and socket is a member of singleslider:: and
    the one you new in constructor
    socket = new QTcpSocket(this); ?


  • Moderators

    @dflass said:

    void singleslider::on_horizontalSlider_valueChanged(int value)
    {
    socket->write("3");
    socket->flush();
    }

    You are sending a character '3' (one byte) and not the integer value 3. The ASCII value of '3' is completely different.


  • Qt Champions 2016

    @dflass
    Hello,
    One thing that peeked my attention is this constructor:

    socket = new QTcpSocket(this);   // <<< This is never(!) used
    // ...
    
    if (!server->listen(QHostAddress::Any,1234))
    {
        qDebug()<< "not started";
    }
    else
    {
        qDebug() << "Server Started";
        socket = server->nextPendingConnection();  // <<< Are you sure that you have a pending connection? No pending connection means setting the socket variable to NULL
    }
    

    You have the following problem(s):

    1. You create a socket that you never intend to use (the first line is exactly that).
    2. You request the next pending connection, even though you're not sure if such a connection is queued (the function returns NULL and sets your QSqlSocket pointer to NULL).
    3. You try to dereference a NULL pointer:
    void singleslider::on_horizontalSlider_valueChanged(int value)
    {
       socket->write("3");  // <<< It crashes here because socket is NULL
    }
    

    To have that working properly, connect the QTcpServer::newConnection signal to a slot in your program and only then retrieve the socket handle.

    Kind regards.



  • @koahnig

    Yes, firstly I'm trying to get something to be successful before worrying about data streams.

    @kshegunov

    Does the if else statement not prevent a the null pointer?
    It seems as if there is not an incoming connection the qDebug will just output "not started"


  • Moderators

    @dflass

    There are a couple of open issues in your code.
    @kshegunov tries already to point you to the problem of your listen use.
    When the port 1234 is available it will return true. But that does not mean that there is already a waiting connection. Therefore the nextPendngConnection will return a null pointer. You need to use signals and slots.
    Therefore I am suggesting to you to go through the network fortune server and fortune client examples.

    Once again the difference between sending a char containing the ASCII representation of '3' and sending an integer holding 3 is very significant. The char is one byte and the integer would be probably in this case 4 bytes.

    int i = 3; 
    char chr = i;      // equivalent to char chr = 3;
    char chr3 = '3';
    

    You can do above code. A conversion between integers and chars is done here by the compiler. In most circustances it will complain and issue at least some warnings. However, you can do this.
    However, you cannot do this over a TCP connection. When sending a char you need to read on the other side a char and the same with ints.


  • Qt Champions 2016

    @dflass

    Does the if else statement not prevent a the null pointer?

    Well, not really, no. QTcpServer::listen doesn't block, its return value just indicates whether or not your request to listen to a port was successful. This doesn't at all guarantee that you have pending connections for that server socket. As @koahnig pointed out, you should use signals and slots to connect to the interesting events generated by your server socket and handle them appropriately. Do follow his suggestion, and look at the server/client examples, which will give you a good overview on how to setup a TCP server/client application properly.

    Kind regards.


Log in to reply
 

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