我正在尝试编写一段代码,定期尝试使用QTcpSocket连接到服务器,直到服务器启动并准备就绪。客户端还应该在服务器关闭时自动并定期尝试重新连接,直到它再次启动或用户手动关闭程序。
我所做的是订阅QTcpSocket的连接和错误信号。当我捕获错误信号时,我基本上再次调用connectToHost方法。
我的代码会定期尝试连接到主机,直到服务器准备就绪(此部分正常)。但是,问题是当服务器关闭时它永远不能重新连接。当连接断开时,我按预期得到RemoteHostClosedError。但是,在同一个方法(我捕获RemoteHostClosedError)中再次调用connectToHost方法后,我什么都没得到。甚至QTcpSocket对象也不会发出错误信号。
我在下面提供了我的代码。
TcpServerConnector::TcpServerConnector( SocketSettings socketSettings, QObject* parent)
: QObject(parent), socket(new QTcpSocket())
{
this->connect(this->socket, SIGNAL(connected()), this, SLOT(connectionSuccess_Handler()), Qt::DirectConnection);
this->connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError_Handler(QAbstractSocket::SocketError)), Qt::DirectConnection);
}
void TcpServerConnector::connectionError_Handler( QAbstractSocket::SocketError error )
{
switch (error)
{
case QAbstractSocket::AddressInUseError:
this->logger.log(LogLevel::ERR, "SOCKET ERROR: Address is already in use");
break;
case QAbstractSocket::ConnectionRefusedError:
this->logger.log(LogLevel::ERR, "SOCKET ERROR: Connection refused");
break;
case QAbstractSocket::HostNotFoundError:
this->logger.log(LogLevel::ERR, "SOCKET ERROR: Host not found");
break;
case QAbstractSocket::RemoteHostClosedError:
this->logger.log(LogLevel::ERR, "SOCKET ERROR: Remote host closed");
break;
}
this->socket->abort();
this->socket->close();
this->logger.log(LogLevel::DEBUG, "Reconnecting...");
SystemUtil::sleepCurrentThread(1000);
this->socket->connectToHost(ip_address, port);
}
}
我在调用connectToHost方法之前和之后检查QTcpSocket的状态(我在这里给出的最后一行)。在调用connectToHost之前,状态为UnconnectedState,在调用connectToHost后,其状态变为Connecting。没什么意外的。但是,它既不能连接到服务器,也不会发出错误信号。
有什么想法吗?
注意:QTcpSocket的connectToHost metod是第一次在内部调用。
答案 0 :(得分:5)
对于那些可能遇到类似情况的人来说,QTcpSocket的重置方法解决了这个问题。
答案 1 :(得分:1)
我遇到了这样的问题。
我做错了是我尝试QTcpSocket::connectToHost()
来自我班级的一个插槽,连接到QTcpSocket::error()
信号。最后,我在post找到了解决方案。
如果我没有弄错的话,问题是你无法从这个插槽中重新连接,因为在QTcpSocket::error()
信号被激活后,控制流从你的处理程序返回到{{1}发出这个信号的方法,或者你以某种方式打破套接字的逻辑。
不是优雅,但仍然是单行代码解决方案是致电QTcpSocket
一旦您的QMetaObject::invokeMethod(m_socket, "connectToHost", Qt::QueuedConnection);
广告位被调用。
请注意,如果您在自定义方法上调用handle_socket_error()
,则必须将其注册为插槽。
QMetaObject::invokeMethod
信号documentation中提到了这个问题。
答案 2 :(得分:0)
我遇到了这种情况, 这是解决方案:
connect(&tcpClient, SIGNAL(disconnected()), SLOT(ReconnectToHost()));
void ReconnectToHost(){tcpClient.connectToHost(theServerAddress, port);}