我的问题标题应该足够了。我已经尝试过(没有成功):
__attribute__((destructor))
:void sendToServerAtExit() __attribute__((destructor)) {
mySocket->write("$%BYE_CODE%$");
}
调用应用程序析构函数,但套接字已断开连接,我无法写入服务器。
atexit()
,但TCP连接已丢失,因此我无法向服务器发送任何内容。atexit(sendToServerAtExit); // is the same function of point 1
我找到的解决方案是每秒检查所有连接的套接字是否仍然连接,但我不想这样做效率低下。它只是一个临时解决方案。此外,我希望其他应用程序(甚至是网络应用程序)可以加入我的控制台应用程序的聊天室,而且我不想每秒都要求数据。
我该怎么办?
答案 0 :(得分:2)
处理以下信号(QTcpSocket
继承自QAbstractSocket
)
void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
在调用的广告位中,检查socketState
是否为QAbstractSocket::ClosingState
。
QAbstractSocket::ClosingState
表示套接字即将关闭。
答案 1 :(得分:1)
您可以将插槽连接到断开信号。
connect(m_socket, &QTcpSocket::disconnected, this, &Class::clientDisconnected);
您还可以使用以下插槽了解哪个用户已断开连接:
void Class::clientDisconnected
{
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if(client)
{
// Do something
client->deleteLater();
}
else
{
// Handle error
}
}
如果您有连接池,此方法很有用。如果您只有一个连接,也可以使用它,但在nullptr
之后不要忘记client->deleteLater()
。
答案 2 :(得分:0)
如果我理解你的问题是正确的,你想通过TCP发送数据,以通知远程计算机你正在关闭套接字。
从技术上讲,这可以通过听取QIODevice::aboutToClose()
或QAbstractSocket::stateChanged()
信号在Qt中完成。
但是,如果您慷慨地退出程序并通过向远程计算机发送QTcpSocket
数据包来关闭FIN
。这意味着在远程计算机上
将通知正在运行的程序TCP连接已完成。例如,如果远程程序也使用QTcpSocket
,QAbstractSocket::disconnected()
信号将被发出。
当其中一个程序没有慷慨地退出(崩溃,硬件问题,电缆拔掉等)时,会出现真正的问题。在这种情况下,TCP FIN
数据包将
不发送,远程计算机永远不会收到TCP连接另一端断开连接的通知。 TCP连接将在几分钟后超时。
但是,在这种情况下,您无法将最后一段数据发送到服务器。
最后,唯一的解决方案是不时地发送“我在这里”数据包。尽管你声称它是无效的,但它是一种广泛使用的技术,它还具有工作原理的优势。