qt sokect五秒掉线重连_QTcpSocket状态总是连接,甚至拔出以太网线

I have a QTcpSocket and I am reading into a loop. Each time a full packet has been read, or there has been an error, I manually check the status of the socket inside the loop, with:

while(true){

if(socket->state()==QAbstractSocket::ConnectedState){

qDebug()<

if(socket->waitForReadyRead(2000)){

//...

}

When I execute de program, once connected and the loop starts, it always prints qDebug()<

The problem is that disconnections are not detected. If I disconnect from network from the OS options, or even if I unplug the ethernet wire, it behaves the same: Socket state equals QAbstractSocket::ConnectedState, so it goes on, but without receiving anything of course.

I also tried to detect disconnections connecting disconnected() signal (after fist connection) to a reconnect function:

// Detect disconnection in order to reconnect

connect(socket, SIGNAL(disconnected()), this, SLOT(reconnect()));

void MyClass::reconnect(){

qDebug()<

panelGUI->mostrarValueOffline();

socket->close();

prepareSocket((Global::directionIPSerialServer).toLocal8Bit().data(), 8008, socket);

qDebug()<state();

}

But signal is never emited, because this code is never executed. Which is logical, since it looks like socket state is always ConnectedState.

If I plug again, connection is restored and starts to receive data again, but I do want to detect disconnections to show "Disconnected" at the GUI.

Why is QTcpSocket behaving this way, and how can I solve this problem?

EDIT: I'm creating socket at the class constructor, and then initialising calling prepareSocket function:

socket = new QTcpSocket();

socket->moveToThread(this);

bool prepareSocket(QString address, int port, QTcpSocket *socket) {

socket->connectToHost(address, port);

if(!socket->waitForConnected(2000)){

qDebug()<errorString();

sleep(1);

return false;

}

return true;

}

解决方案

Finally found the solution in this Qt forum:

If no data is exchanged for a certain while, TCP will start sending

keep-alive segments (basically, ACK segments with the acknowledgement

number set to the current sequence number less one). The other peer

then replies with another acknowledgement. If this acknowledgment is

not received within a certain number of probe segments, the connection

is automatically dropped. The little problem is that the kernel starts

sending keep-alive segments after 2 hours since when the connection

becomes idle! Therefore, you need to change this value (if your OS

allows that) or implement your own keep-alive mechanism in your

protocol (like many protocols do, e.g. SSH). Linux allows you to

change it using setsockopt:

int enableKeepAlive = 1;

int fd = socket->socketDescriptor();

setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));

int maxIdle = 10; /* seconds */

setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));

int count = 3; // send up to 3 keepalive packets out, then disconnect if no response

setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));

int interval = 2; // send a keepalive packet out every 2 seconds (after the 5 second idle period)

setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值