QTcpSocket 未连接

QTcpSocket Not Connecting

我正在尝试设置 QTcpSocket 连接。我正在开发一个涉及通过单个 TCP 套接字进行双向通信的简单应用程序。

我正在通过 运行 连接同一应用程序的两个实例并将它们连接到 QHostAddress::Broadcast 来测试我的代码。当我 运行 我的代码时,我得到以下状态序列:

  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."

编辑:经过进一步调试,我发现第 4 项实际上是 连接被拒绝错误

下面是我的代码:

#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!"));
}

如果有人能帮助我确定为什么会出现此错误,我将不胜感激。我是 Qt 和网络的新手,所以我可能遗漏了一些相当明显的东西。

提前致谢!

您不能将广播地址用于 TCP。因此,您可以选择单播地址(指向单个目的地的地址),或使用 QUdpSocket.

您可以在文档中找到这两种情况的示例:http://doc.qt.io/qt-5/examples-network.html

事实上,您缺少一个基本的东西:要能够连接到套接字,您需要有一个正在侦听该地址和端口的进程。 因此,您实际上可以使用同一软件的两个实例来建立连接,但两个实例之一必须充当服务器(并监听),而第二个实例必须尝试建立连接。 到目前为止你只实现了第二部分。

所以你应该添加如下内容:

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

当然,您需要在小部件上有一个监听按钮,并在您的 运行 个实例之一上使用它。