Reputation: 1114
In mainwindow
there is a slot MainWindow::establish_connection
in which I'm trying to invoke Server::establish_connection
in different thread:
void MainWindow::establish_connection(const std::string& nickname,
const std::string& ip, int port)
{
auto thread = new QThread(this);
remote_server = new Server(nickname, ip, port);
connect(thread, SIGNAL(started()), remote_server, SLOT(establish_connection()));
connect(remote_server, SIGNAL(connected()), this, SLOT(connection_established()));
connect(remote_server, SIGNAL(readyRead()), this, SLOT(handle_reply()));
connect(remote_server, SIGNAL(error(QAbstractSocket::SocketError)), this,
SLOT(connection_failed(QAbstractSocket::SocketError)));
connect(remote_server, SIGNAL(stop_thread()), thread, SLOT(quit()));
thread->start();
}
Server::establish_connection
method:
void Server::establish_connection()
{
master_socket = std::move(
std::unique_ptr<QTcpSocket>(new QTcpSocket(nullptr)));
connect(master_socket.get(), SIGNAL(connected()), SIGNAL(connected()));
connect(master_socket.get(), SIGNAL(readyRead()), SIGNAL(readyRead()));
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
master_socket->connectToHost(ip.c_str(), port);
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
emit stop_thread();
}
but when error
signal emits, MainWindow::connection_failed
invokes twice.
void MainWindow::connection_failed(QAbstractSocket::SocketError e)
{
QString err_msg = remote_server->get_socket()->errorString();
qDebug() << err_msg;
}
Output:
"Connection refused"
"Connection refused"
How to prevent this issue?
Upvotes: 0
Views: 656
Reputation: 1191
Here you reemit the signal error from master_socket : connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
This seems to be number one to me.
And here you emit it yourself after timeout:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
This seems to be your number two.
I think while you wait for the timeout error()
it is already emitted and relayed by your connect()
. And afterwards you emit it yourself again. This seems to be super fluent.
Test whether removing this explicit emit does the trick for you.
Alternatively you can put the line connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
after your if
condition to get all errors from that point on. No need to disconnect.
Or put it in the else
branch because you are only interested in any more errors if a connection could be established:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
} else {
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
}
Both should work.
Upvotes: 1