QTcpSocket Not Connecting

3.9k views Asked by At

I am trying to setup a QTcpSocket connection. I am working on a simple application that involves bidirectional communication via a single TCP socket.

I am testing my code by running two instances of the same application and connecting both to QHostAddress::Broadcast. When I run my code, I get the following sequence of states:

  1. QAbstractSocket::HostLookupState -- "The socket is performing a hostname lookup."
  2. QAbstractSocket::ConnectingState -- "The socket has started establishing a connection."
  3. QAbstractSocket::UnconnectedState -- "The socket is not connected."
  4. QAbstractSocket::SocketError -- "Permission Denied."

EDIT: After some further debugging, I found that item #4 was actually a Connection Refused Error.

Below is my code:

#include "widget.h"
#include "ui_widget.h"
#include <string>

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

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

void Widget::on_connect_clicked()
{
    if (!m_socket)
    {
        m_socket = new QTcpSocket(this);
        m_socket->setSocketOption(QAbstractSocket::KeepAliveOption,1);
    }

    connect(m_socket, SIGNAL(readyRead()), SLOT(readSocketData()), Qt::UniqueConnection);
    connect(m_socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(connectionError(QAbstractSocket::SocketError)), Qt::UniqueConnection);
    connect(m_socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(tcpSocketState(QAbstractSocket::SocketState)), Qt::UniqueConnection);
    connect(m_socket, SIGNAL(disconnected()), SLOT(onConnectionTerminated()), Qt::UniqueConnection);
    connect(m_socket, SIGNAL(connected()), SLOT(onConnectionEstablished()), Qt::UniqueConnection);

    if(!(QAbstractSocket::ConnectedState == m_socket->state()))
    {
        m_socket->connectToHost(QHostAddress::Broadcast, ui->port->value(), QIODevice::ReadWrite);
    }

}

void Widget::readSocketData()
{
    while(m_socket->bytesAvailable())
    {
        QTextStream T(m_socket);
        ui->incoming->addItem(T.readAll());
    }
}


void Widget::on_send_clicked()
{
    sendMessage(ui->message->text());
}

void Widget::sendMessage(QString msg)
{
    QByteArray dataSend;
    QDataStream dataStream(&dataSend, QIODevice::WriteOnly);
    dataStream.setByteOrder(QDataStream::LittleEndian);
    dataStream << msg.length();
    dataSend.append(msg);

    m_socket->write(dataSend, dataSend.length());
}

void Widget::connectionError(QAbstractSocket::SocketError socketError)
{
    std::string errorStr = "ERROR: " + m_socket->errorString().toStdString();
    QMessageBox::information(this, tr("Tcp Server Client"), tr(errorStr.c_str()));
}

void Widget::tcpSocketState(QAbstractSocket::SocketState socketState)
{
    switch (socketState) {
        case QAbstractSocket::UnconnectedState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is not connected."));
            break;
        case QAbstractSocket::HostLookupState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is performing a hostname lookup."));
            break;
        case QAbstractSocket::ConnectedState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("A connection is established."));
            break;
        case QAbstractSocket::ConnectingState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket has started establishing a connection."));
            break;
        case QAbstractSocket::BoundState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is bound to an address and port."));
            break;
        case QAbstractSocket::ClosingState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is about to close."));
            break;
        case QAbstractSocket::ListeningState:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("The socket is listening."));
            break;
        default:
            QMessageBox::information(this, tr("Tcp Server Client"), tr("Unknown State."));
    }
}

void Widget::onConnectionTerminated()
{
    QMessageBox::information(this, tr("Tcp Server Client"), tr("Disconnected."));
}

void Widget::onConnectionEstablished()
{
    QMessageBox::information(this, tr("Tcp Server Client"), tr("Connected!"));
}

I would appreciate it greatly if someone could help me identify why this error might be coming up. I am new to Qt and networking, so there might be something fairly obvious that I'm missing.

Thanks in advance!

2

There are 2 answers

0
Marco On BEST ANSWER

In fact there is a basic thing that you are missing: to be able to connect to a socket you need have a process that is listening on that address and port. So you can actually use two instances of the same software to make a connection but one of the 2 instances must be acting as server (and listen) and the second instance must try to do the connection. So far you have only implemented the second part.

So you should add something like:

void Widget::on_listen_clicked()
{
    if (!m_socket->listen()) {
        QMessageBox::information(this, tr("Tcp Server"),tr("Error listening!"));
    }
}

And of course you need to have a listen button on your widget and use it on one of your running instances.

3
alexisdm On

You can't use a broadcast address with TCP. So, you can either choose a unicast address (an address pointing to a single destination), or use a QUdpSocket.

You can find examples in the documentation for both cases: http://doc.qt.io/qt-5/examples-network.html