先简单介绍一下QTcpSocket上面常用的几个信号与函数

信号名 触发条件
connected() 连接成功时
disconnected() 断开连接时
error(QAbstractSocket::SocketError socketError) 产生错误时,附带错误码
hostFound() 调用connectToHost,并且找到主机后发出,还没连接上
proxyAuthenticationRequired(const QNetworkProxy & proxy, QAuthenticator * authenticator) This signal can be emitted when a proxy that requires authentication is used. The authenticator object can then be filled in with the required details to allow authentication and continue the connection.
stateChanged(QAbstractSocket::SocketState socketState) 连接状态发生改变时,会发出,附带当前状态的状态码
常用函数 简介
connectToHost 连接
disconnectFromHost 断开连接,会等待数据发送完毕
abort 立即断开,丢弃数据
state 查看当前socket的状态
error 查看当前socket的错误
close 关闭包括(I/O设备,连接,socket,重置各种数据)
waitForConnected 阻塞,等待连接,连接成功发出true,超时发出false
waitForReadyRead 阻塞,等待数据和readyRead信号,超时反回false
waitForBytesWritten 阻塞,至少写入一个字节和发出byteswrite信号后才发出true,超时发出false
waitForDisconnected 阻塞,等待断开,断开成功发出true,超时发出false
read 读取,可以每次读取一定量的数据
readLine 读取一行数据
readAll 读取缓冲区所有数据
write 写入数据

断线重连机制原理

​ 下面两种方法原理其实都一样,检查socket的状态,如果是断开,开启重新连接机制,连接成功,关掉机制。

一、使用定时器

  • 基于QTcpSocket的派生类,信号和槽在构造函数中连接

  • 在定时器的timeout信号触发时,对应的槽函数处理为

    1
    2
    3
    4
    5
    if( 判断当前socket的状态,没有连接上 ){
    socket连接
    }else {
    定时器stop
    }
  • 在socket的disconnected信号发出时,对应的槽函数处理为

    1
    2
    3
    abort();
    disconnectFromHost();
    定时器启动

    缺点是与当前线程占相同的资源,优点个人感觉实现起来非常简单。

二、使用线程

  • 基于QThread的派生类,信号和槽,socket创建,需要在调用线程start前创建好

  • 在线程的run方法中,处理如下,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    while(threadRun){
    if( socket没有连接上 ){
    connectToHost;
    waitForConnected(); 连接并产生阻塞,退出当前线程
    }
    if( socket没有连接上 ){
    continue;
    }
    waitForReadyRead(); 来到这里表示socket连接成功,产生阻塞,等待数据到来
    }
  • 因为socket的处理是在新的线程中运行,接收到数据需要发送到主线程中,readyRead对应的槽函数处理为

    1
    2
    3
    4
    while( bytesAvailable()>0 ){
    byteArray=readAll();
    emit signalReadyRead(byteArray);
    }