QTcpSocket не подключается
Я пытаюсь настроить соединение QTcpSocket. Я работаю над простым приложением, которое включает двунаправленную связь через один сокет TCP.
Я тестирую свой код, запустив два экземпляра одного и того же приложения и подключив оба к QHostAddress::Broadcast. Когда я запускаю свой код, я получаю следующую последовательность состояний:
- QAbstractSocket:: HostLookupState - "Сокет выполняет поиск имени узла".
- QAbstractSocket:: ConnectingState - "Сокет начал устанавливать соединение".
- QAbstractSocket:: UnconnectedState - "Сокет не подключен".
- QAbstractSocket:: SocketError - "Отказано в доступе ".
РЕДАКТИРОВАТЬ: После некоторой дальнейшей отладки, я обнаружил, что элемент № 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 ответа
На самом деле есть одна базовая вещь, которую вы упускаете: чтобы иметь возможность подключиться к сокету, вам нужен процесс, который прослушивает этот адрес и порт. Таким образом, вы можете использовать два экземпляра одного и того же программного обеспечения для установления соединения, но один из двух экземпляров должен действовать как сервер (и прослушивать), а второй должен пытаться установить соединение. Пока вы реализовали только вторую часть.
Поэтому вы должны добавить что-то вроде:
void Widget::on_listen_clicked()
{
if (!m_socket->listen()) {
QMessageBox::information(this, tr("Tcp Server"),tr("Error listening!"));
}
}
И, конечно, вам нужно иметь кнопку прослушивания на вашем виджете и использовать ее на одном из ваших запущенных экземпляров.
Вы не можете использовать широковещательный адрес с TCP. Таким образом, вы можете выбрать одноадресный адрес (адрес, указывающий на один пункт назначения) или использовать QUdpSocket
,
Вы можете найти примеры в документации для обоих случаев: http://doc.qt.io/qt-5/examples-network.html