• 6525阅读
  • 2回复

[提问]多线程Qtcpsocket状态不改变的问题 [复制链接]

上一主题 下一主题
离线14dzqiu
 

只看楼主 倒序阅读 楼主  发表于: 2016-10-07
— 本帖被 XChinux 从 其它技术开发讨论区 移动到本区(2016-10-07) —
简单说一下,首先我在主线程开了一个tcpserver,在重现它的虚函数incomingConnection(qintptr handle),让它能够发出信号 emit incomingsock(handle),并连接到主线程的一个槽CreateThread,在这个槽中我创建线程来监控这些新连接,并在线程的run函数中new一个qtcpsocket来控制这个连接,但是我在连接中发现我的Qtcpsocket->state()是不变的,就算我把下位机的WiFi模块断电,qDebug出来的一样还是connectedState。


一下是我的各个代码:
首先是我对QTcpserver的继承
#include "mytcpserver.h"
//#include "tcpthread.h"
myTcpServer::myTcpServer(QWidget * parent):QTcpServer(parent)
{

}

void myTcpServer::incomingConnection(qintptr handle)
{
    emit incomingsock(handle);
}




随后我在主线程中建立它,并连接信号与槽
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->HostIP=Getip();
    this->tcpServer=new myTcpServer(this);
    connect(this->tcpServer,SIGNAL(incomingsock(qintptr)),this,SLOT(CreateTcpThread(qintptr)));
    this->LoadClientInfo();
    this->TableInit();
}


而槽函数中是:
void MainWindow::CreateTcpThread(qintptr newsocket)
{
     TcpThread *t = new TcpThread(newsocket);
     t->start();
  //   connect(t,SIGNAL(Recframe(int,QString)),this,SLOT(ThreadShow(int,QString)));

}



随后我写的线程程序是:
#include "tcpthread.h"
#include "esp8266.h"
TcpThread::TcpThread(qintptr handle)
{
    this->stop=false;
    this->Device=0;
    this->RxFlag=false;
    this->newhandle=handle;
    connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));

}
void TcpThread::run()
{
    this->socket=new QTcpSocket();
    this->socket->setSocketDescriptor(this->newhandle);



    QTime connectTime=QTime::currentTime();
    connect(socket,SIGNAL(disconnected()),this,SLOT(quitThread()));
    connect(socket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(quitThread()),Qt::DirectConnection);

    int i;
    for(i=0;i<3;i++)
    {
     if(socket->waitForReadyRead(2000))
     {
         buff=socket->readAll();
         if(Esp8266::FrameCheck(buff))
         {
             int deviceNum=(buff[4]-'0')*10+buff[5]-'0';
             if(CheckMac(deviceNum))
             {
                msleep(1000);
                this->Device=deviceNum;
                this->socket->write("Connection permission");
                this->socket->flush();
             }
                 break;
         }
     }
    }
    if(i==3)
        socket->close();
    while(!stop)
    {
        qDebug()<<socket->state();
        msleep(200);
//        if(this->socket->waitForDisconnected(3000))
//        {
//            qDebug()<<"disconnect";
//            break;
//        }
//        msleep(3000);
//        this->socket->write(Esp8266::GetFrame(ACK,this->Device).toLatin1());
//        this->socket->flush();
//        if(this->socket->waitForReadyRead(3000))
//        {
//           // qDebug()<<QTime::currentTime().toString("hh:mm:ss 收到:")<<this->socket->readAll();
//        }
//        else
//        {
//            qDebug()<<"disconnect:"<<connectTime.toString("hh:mm:ss To ")<<QTime::currentTime().toString("hh:mm:ss")<<connectTime.msecsTo(QTime::currentTime())/1000;
//            break;
//        }
    //    sleep(10);
    }


}



void TcpThread::quitThread()
{
    qDebug()<<socket->errorString();
    qDebug()<<"lll";
    stop=true;
}



很不解,我用qDebug显示socket的状态,就算我让连接的另一端重启甚至是断电好长一段时间,这个state还是没有变:显示如下:

QAbstractSocket::ConnectedState
QAbstractSocket::ConnectedState
QAbstractSocket::ConnectedState
QAbstractSocket::ConnectedState
...


请教是不是我有什么没有设置对?请赐教,第一次用多线程写服务器。

离线kaon

只看该作者 1楼 发表于: 2016-10-08
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:

http://stackoverflow.com/questions/10445122/qtcpsocket-state-always-connected-even-unplugging-ethernet-wire
离线14dzqiu

只看该作者 2楼 发表于: 2016-10-09
回 kaon 的帖子
kaon:http://stackoverflow.com/questions/10445122/qtcpsocket-state-always-connected-even-unplugging-ethernet-wire (2016-10-08 18:32) 

受益匪浅,但是我想知道QTcpsocket里面那些disconnect这些信号是什么情况才会发出的呢?
快速回复
限100 字节
 
上一个 下一个