QTcpSocket未连接

时间:2015-06-25 20:35:05

标签: c++ qt sockets tcp qtcpsocket

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

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

  1. QAbstractSocket :: HostLookupState - “套接字正在执行主机名查找。”
  2. QAbstractSocket :: ConnectingState - “套接字已开始建立连接。”
  3. QAbstractSocket :: UnconnectedState - “套接字未连接。”
  4. QAbstractSocket :: SocketError - “权限被拒绝。”
  5. 编辑:经过一些进一步调试后,我发现第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和网络的新手,因此我可能会有一些相当明显的东西。

    提前致谢!

2 个答案:

答案 0 :(得分:0)

您无法使用TCP广播地址。因此,您可以选择单播地址(指向单个目的地的地址),也可以使用QUdpSocket

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

答案 1 :(得分:0)

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

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

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

当然,您需要在窗口小部件上设置一个监听按钮,并在其中一个正在运行的实例上使用它。