【发布时间】:2012-05-13 18:42:10
【问题描述】:
我有一个 QTcpSocket,我正在读入一个循环。每次读取一个完整的数据包,或者出现错误时,我都会手动检查循环内套接字的状态,使用:
while(true){
if(socket->state()==QAbstractSocket::ConnectedState){
qDebug()<<"Socket status: connected. Looking for packets...";
if(socket->waitForReadyRead(2000)){
//...
}
当我执行de程序时,一旦连接并开始循环,它总是打印qDebug()<<"Socket status: connected. Looking for packets...";然后停留在waitForReadyRead,直到准备好读取一些数据。
问题是没有检测到断开连接。如果我从操作系统选项断开网络连接,或者即使我拔下以太网线,它的行为也是一样的:套接字状态等于QAbstractSocket::ConnectedState,所以它会继续,但当然没有收到任何东西。
我还尝试检测将disconnected() 信号(在第一次连接后)连接到重新连接函数的断开连接:
// Detect disconnection in order to reconnect
connect(socket, SIGNAL(disconnected()), this, SLOT(reconnect()));
void MyClass::reconnect(){
qDebug()<<"Signal DISCONNECTED emitted. Now trying to reconnect";
panelGUI->mostrarValueOffline();
socket->close();
prepareSocket((Global::directionIPSerialServer).toLocal8Bit().data(), 8008, socket);
qDebug()<<"Reconnected? Status: "<<socket->state();
}
但是信号永远不会发出,因为这段代码永远不会被执行。这是合乎逻辑的,因为它看起来像套接字状态总是ConnectedState。
如果我再次插入,连接会恢复并再次开始接收数据,但我确实想检测断开连接以在 GUI 上显示“已断开连接”。
为什么 QTcpSocket 会这样,我该如何解决这个问题?
编辑:我在类构造函数中创建套接字,然后初始化调用 prepareSocket 函数:
socket = new QTcpSocket();
socket->moveToThread(this);
bool prepareSocket(QString address, int port, QTcpSocket *socket) {
socket->connectToHost(address, port);
if(!socket->waitForConnected(2000)){
qDebug()<<"Error creating socket: "<<socket->errorString();
sleep(1);
return false;
}
return true;
}
【问题讨论】:
-
拔掉电缆等了多长时间?
-
不知道... 10 秒? POSIX 套接字确定它们已断开连接的必要性要少得多。我应该等多久?
-
TCP 超时远高于此。至少等待几分钟。
-
在这个类似的问题stackoverflow.com/questions/10331016 中,我提到(在我回答后的cmets)TCP_KEEPALIVE 可能有助于在一段时间后检测网络断开连接。那有帮助吗?您在寻找更快的方法吗?
-
但是对于 POSIX 套接字,它们需要大约一秒钟才能开始说“网络无法访问”。为什么 QTcpSockets 没有?在这 2 分钟之前没有任何方法可以检测到这一点吗? (不使用保活协议)
标签: c++ qt network-programming state qtcpsocket