QTcpSocket::disconnected() 在一些情况下不能被触发

Gaosiy 2019-05-08 10:29:41
如题,做一个网络编程项目时遇到检测不到断开的情况。
最迷惑我的是当我用软件模拟连接的时候这个信号可以马上触发。
但是使用硬件连接时,我的两个硬件一个可以检测到(但是已经是断开连接10s以后了)另一个硬件完全检测不到。
先上代码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<qfile.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
server = new QTcpServer();
connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

int port = 5007;
if(!server->listen(QHostAddress::Any,port))
{
ui->label_listen->setText("Cant listen");
qDebug()<<server->errorString();
return;
}

}

MainWindow::~MainWindow()
{
server->close();
server->deleteLater();
delete ui;
}

void MainWindow::server_New_Connect()
{
socket=server->nextPendingConnection();
QObject::connect(socket,&QTcpSocket::readyRead,this,&MainWindow::socket_Read_Data);
//做了connect,但是当硬件断开的时候不能触发。
QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
ui->pushButton_send->setEnabled(true);
ui->label->setText("new Connection");
qDebug() << "new Connection";
}

void MainWindow::socket_Read_Data()
{

//里边做了一些数据处理
socket->write("0123423415343245");
socket->flush();

}

void MainWindow::socket_Disconnected()
{
//不会被调用
}


为了解决这个问题,我加了个QTimer去定时查看socket的连接状态
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<qfile.h>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{

server = new QTcpServer();
connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

int port = 5007;
if(!server->listen(QHostAddress::Any,port))
{
ui->label_listen->setText("Cant listen");
qDebug()<<server->errorString();
return;
}

ui->label_listen->setText("Listening");


}

MainWindow::~MainWindow()
{
server->close();
server->deleteLater();
delete ui;
}


void MainWindow::server_New_Connect()
{
socket=server->nextPendingConnection();
QObject::connect(socket,&QTcpSocket::readyRead,this,&MainWindow::socket_Read_Data);
QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);
ui->pushButton_send->setEnabled(true);
ui->label->setText("new Connection");
qDebug() << "new Connection";
// I set a timer to print socket state every one second.
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::Psocket);
timer->setInterval(1000);
timer->start(1000);
}

void MainWindow::socket_Read_Data()
{
//ignore
//write改短了以后竟然第二个设备也能检测到断开了
socket->write("01234");
socket->flush();
}

void MainWindow::socket_Disconnected()
{
//can be called
}

void MainWindow::Psocket()
{
//I think the write("test") do something because when I delete the write, it does not work again
qDebug()<<socket->state();

}


这里打印一直是connected状态,但是有一个硬件会在十多秒之后,从connected变为disconnected,另外一个不会,然后我把read_data函数中的write内容减少了一部分,发现那个不能的设备过十几秒也能触发了!
但是这个十几秒的延迟我不想存在,我现在非常疑惑,请各位帮忙分析一下原因

...全文
5189 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
储哈哈 2019-09-05
  • 打赏
  • 举报
回复
https://blog.csdn.net/weixin_37633951/article/details/90108224
我之前遇到是由于processEvents()函数导致的
Gaosiy 2019-05-20
  • 打赏
  • 举报
回复
引用 2 楼 Huanyu414 的回复:
建议先了解一下网络相关知识,收不到是正常的,一般都用心跳来处理类似问题。
自己后来研究了一下解决了这个问题,加了个定时器,一定时间内收不到客户端的消息就自动disconnected。但是对于这个问题我仍有疑问: QT对于客户端的异常断开其实是没有监测机制的,但是后来我经过了大量的实验发现,虽然客户端硬件直接断开以后disconnected不是一定能检测到的,但是在客户端与主机通信一定次数以上,就可以,比如我的两个设备,一个是1000hz的频率,一个是100hz,1000的高概率可以检测到断连,100的需要通信一段时间之后也高概率可以。 这就让我很奇怪,你要是说没有异常检测机制你完全检测不到我能理解,有时候行有时候不行的这种真的理解不到
Gaosiy 2019-05-20
  • 打赏
  • 举报
回复
自己后来研究了一下解决了这个问题,加了个定时器,一定时间内收不到客户端的消息就自动disconnected。但是对于这个问题我仍有疑问: QT对于客户端的异常断开其实是没有监测机制的,但是后来我经过了大量的实验发现,虽然客户端硬件直接断开以后disconnected不是一定能检测到的,但是在客户端与主机通信一定次数以上,就可以,比如我的两个设备,一个是1000hz的频率,一个是100hz,1000的高概率可以检测到断连,100的需要通信一段时间之后也高概率可以。 这就让我很奇怪,你要是说没有异常检测机制你完全检测不到我能理解,有时候行有时候不行的这种真的理解不到
Gaosiy 2019-05-09
  • 打赏
  • 举报
回复
引用 2 楼 Huanyu414 的回复:
建议先了解一下网络相关知识,收不到是正常的,一般都用心跳来处理类似问题。
多谢老哥,我去查一下
yyxmm 2019-05-09
  • 打赏
  • 举报
回复
建议先了解一下网络相关知识,收不到是正常的,一般都用心跳来处理类似问题。
Gaosiy 2019-05-08
  • 打赏
  • 举报
回复
怕是要沉了 有没有用过QTcpSocket的兄弟支援一下

21,441

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧