在mainwindow
中有一个广告位MainWindow::establish_connection
,其中我试图在不同的帖子中调用Server::establish_connection
:
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
方法:
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();
}
但是当error
信号发出时,MainWindow::connection_failed
会调用两次。
void MainWindow::connection_failed(QAbstractSocket::SocketError e)
{
QString err_msg = remote_server->get_socket()->errorString();
qDebug() << err_msg;
}
输出:
"Connection refused"
"Connection refused"
如何防止此问题?
答案 0 :(得分:1)
这里你重新发出master_socket:connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
这对我来说似乎是第一位。
在这里你在超时后自己发出它:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
}
这似乎是你的第二号。
我认为当您等待超时error()
时,它已经被connect()
发出并转发。然后你再次自己发射它。这看起来非常流利。
测试删除此显式发射是否适合您。
或者,您可以将connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
行放在if
条件之后,以便从该点获取所有错误。无需断开连接。
或者将其放在else
分支中,因为如果可以建立连接,您只对任何错误感兴趣:
if (!master_socket->waitForConnected(timeout*1000))
{
emit error(master_socket->error());
} else {
connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
SIGNAL(error(QAbstractSocket::SocketError)));
}
两者都应该有用。