QT client to C server



  • I'm having a hard time trying to connect my QT client to a C server. I know that the server is fully functional. THe problem is in my client. I just want to establish a connection so that later I can send data. First, the client has a login dialog box. After a successful login, he should be redirected to the next menu. I know that the redirection part is correct too. The only problem remains at the connection.
    Here is the code

    @void Login::on_Login_clicked()
    {

    pSocket = new QTcpSocket (this);
    connect (pSocket, SIGNAL(readyRead()), SLOT(waitNextStep()));
    pSocket->connectToHost(ui->lineEdit->text(), ui->lineEdit_2->text().toInt());
    if(pSocket->waitForConnected())
    {
    Menu mMenu;
    mMenu.setModal(true);
    mMenu.exec();
    }
    else
    {
        QMessageBox::critical(this,tr("Error"),tr("Error at Connectt!"));
    }
    

    }@

    I don't get any error. After I complete the line edits with IP and Port and hit connect, the windows freezes for about 15 seconds - is unresponsive. After that I get the Error at Connect dialog box. No matter if I complete with a correct IP and PORT set, the windows still freezes. Any help will be much appreciated.

    @SLOT(waitNextStep())@
    I'm worried mostly about this line. If I'm not planning to do anything with the data now, what shoud the function waitNextStep do ?


  • Moderators



  • Ok so this makes my connect functions look something like

    @connect (pSocket, SIGNAL(connected()), SLOT(handleConnected()));
    connect (pSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT (handleError()));@

    But I'm getting the same result. In the fortuneclient example I couldn't find any waitForConnected function, so I reckon I must get rid of it. But how can I test whether a connection was established?


  • Moderators

    bq. But how can I test whether a connection was established?

    The "connected":http://qt-project.org/doc/qt-5.0/qtnetwork/qabstractsocket.html#connected signal is emitted as soon as the connection is established with the server.
    Thus your handleConnected() will get called.



  • Ok, I understood. Now it's not getting unresponsive. However, it's not doing anything when I press on login - it's not calling handleConnected nor handleError

    @void Login::on_pushButton_clicked()
    {

    pSocket = new QTcpSocket (this);
    connect (pSocket, SIGNAL(connected()), SLOT(handleConnected()));
    connect (pSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT (handleError()));
    pSocket->connectToHost(ui->lineEdit->text(), ui->lineEdit_2->text().toInt());
    

    }@

    The handleConnect looks like
    @void Login::handleConnected()
    {
    Menu mMenu;
    mMenu.setModal(true);
    mMenu.exec();
    }@
    I expect it to open my next dialog box, but fail.
    Sorry for asking so many questions but I really need to make it work.


  • Moderators

    It seems that the client is not getting connected to the server.
    Is the server ip and port correct ?
    Now as you have connected error signal what error you get in handleError() ?
    You can ask as many relevant questions as you like :)



  • The IP and port are both correct.
    In my handleError() i just got a message box with an error message, like this:

    @void Login::handleError()
    {
    QMessageBox::critical(this,tr("Error"),tr("Connection Error"));
    }
    @
    Both handleConnected() and handleError() are declared in private slots section in Login class


  • Moderators

    I should have looked at this first. You need to connect the signal error to slot with proper parameters.
    @
    connect (pSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT (handleError(QAbstractSocket::SocketError)));
    @
    And then in the Slot definition,
    @
    void Login::handleError(QAbstractSocket::SocketError e)
    {
    qDebug() << e;
    }
    @
    Here you would get the actual error.



  • Ok, I understood that. But I'm getting this:

    error: no match for 'operator<<' (operand types are '<unresolved overloaded function type>' and 'QAbstractSocket::SocketError')
    qDebug << e;

    I'm coming from visual studio so i tried to include the using namespace std; but with no result


  • Moderators

    Ofcourse you can use the qDebug() in GUI Application. Just include the header file.
    Whatever error you get during the connection handleError Slot will be called and the error will get printed.


  • Moderators

    Did you put the parentheses for qDebug? "qDebug":http://qt-project.org/doc/qt-4.8/qdebug.html#basic-use is a function.



  • Ok I fixed it and now it runs. But still nothing happens as I press login. I assume the problem is in the login button slot

    @void Login::on_pushButton_clicked()
    {

    pSocket = new QTcpSocket (this);
    connect (pSocket, SIGNAL(connected()), SLOT(handleConnected()));
    connect (pSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT (handleError(QAbstractSocket::SocketError)));
    pSocket->connectToHost("127.0.0.1", 9000);
    

    }@


  • Moderators

    Are you sure it is getting called on click ?
    Have you declared on_pushButton_clicked() as a SLOT ?



  • Yes. I already tested it by opening my next dialog directly. And it works. Isn't there a specific in order in the calling of connect and connectToHost? Or maybe should I place the connectToHost in my handleConnected?


  • Moderators

    The order is correct. All the signals must be connected before calling "connectToHost":http://qt-project.org/doc/qt-5.0/qtnetwork/qabstractsocket.html#connectToHost
    The signal connected() gets emitted when the connection is established.

    Apart from these,
    Which OS are you using ?
    Try changing the port number. It may be blocked by the firewall.



  • I'm on windows with my client. However, the server is on a linux machine. I know i wrote 127.0.0.1 but I did that just to hide the real IP. I tried with ui->lineEdit->text() and ui->lineEdit_2->text().toInt() but still doesn't works.

    The server is designed to listen to 9000 port. I changed the port and no result. After the client is connected, he should send a message to the server. The server should send back the message 'Hello message'. It's pretty straightforward, but I know it's functional since I got connected from a C client and successfully sent and recieved data. I don't think that the message thing should represent a problem, as I should be able to establish a connection anyway. The server uses select for client acceptance - don't know if it's a relevant info


  • Moderators

    Is it a public IP ? May be it is taking time to connect to the Server.
    Try waiting for some time as the handleError() should return some error atleast like QAbstractSocket::SocketTimeoutError or QAbstractSocket::HostNotFoundError or another..

    Another way to test would be to connect to a server using diifferent program.
    As a quick test i using the python server, for e.g you can start a python HTTP server like this,
    @
    python -m SimpleHTTPServer
    @

    or

    @
    python3.3 -m http.server
    @

    By default it listens to port 8000.

    So you can try connecting the client to python server with port 8000.



  • I started a python HTTP server as you said. The server was serving HTTP on 0.0.0.0 port 8000. When I completed the fields of my client with 0.0.0.0 and 8000, i got QAbstractSocket::NetworkError in the bottom side of the screen.

    If i completed with the IP i knew and the port 8000, still nothing as I press login

    It is public but I just connected to the server with a pre-made C client via putty. The server works, it transmited the message back to the C client


  • Moderators

    Can you post your complete client code here ?



  • Sure.
    The login.h
    @#ifndef LOGIN_H
    #define LOGIN_H

    #include <QMainWindow>
    #include <QtNetwork>
    #include <QTcpServer>
    #include <QTcpSocket>
    #include <QMessageBox>
    #include <QDebug>

    namespace Ui {
    class Login;
    }

    class Login : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit Login(QWidget *parent = 0);
    ~Login();
    private slots:
    void on_pushButton_clicked();
    void on_ExitLogin_clicked();
    void handleConnected();
    void handleError(QAbstractSocket::SocketError);
    private:
    Ui::Login *ui;
    QTcpSocket *pSocket;

    };

    #endif // LOGIN_H
    @

    The login.cpp

    @#include "login.h"
    #include "ui_login.h"
    #include <QMessageBox>
    #include "menu.h"
    #include <QtNetwork>
    #include <QLineEdit>
    #include <QTcpSocket>
    #include <QTcpServer>
    #include <QAbstractSocket>
    #include <QDebug>

    using namespace std;

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

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

    void Login::on_pushButton_clicked()
    {
    pSocket = new QTcpSocket (this);
    connect (pSocket, SIGNAL(connected()), SLOT(handleConnected()));
    connect (pSocket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT (handleError(QAbstractSocket::SocketError)));
    pSocket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt());

    }

    void Login::on_ExitLogin_clicked()
    {
    QCoreApplication::instance()->exit();
    }

    void Login::handleConnected()
    {
    Menu mMenu;
    mMenu.setModal(true);
    mMenu.exec();
    }
    void Login::handleError(QAbstractSocket::SocketError e)
    {
    qDebug() << e;
    }
    @

    The main.cpp
    @#include "login.h"
    #include <QApplication>
    #include <QtNetwork>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Login w;
    w.show();
    return a.exec();
    }
    @

    I have some other classes like football, tennis etc since this should be a sports app. However, I have almost no code in them since I just designed them with drag and drop



  • Anyway it seemed like the client was functional and I would like to thank you for your interest. However, I have another problem now and I'd be glad if you could help. My app offers a menu after I pass the login part. There are a lot of options in the menu. I want to communicate with the server via the same socket used at the login part. My pSocket is declared in the Login class and I have no idea how to make all my other functions in other classes to use it.


Log in to reply
 

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