tcpsocket.h
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include <QObject>
#include <QTcpSocket>
class TCPClient : public QObject
{
Q_OBJECT
public:
TCPClient();
~TCPClient();
Q_INVOKABLE void setIP(const QString ip);
QString getIP(){return m_ip;}
Q_INVOKABLE void setPort(const int port);
int getPort(){return m_port;}
void onConnected();
void getMsg();
void closeSocket();
public slots:
int createTcpConnect();
void sendMsg(const QByteArray &data);
signals:
void showMsg(const QByteArray &data);
private:
QTcpSocket *m_tcpsocket;
QString m_ip;
int m_port;
QByteArray m_message;
int m_length;
bool m_bReceive;
};
#endif // TCPSOCKET_H
tcpsocket.cpp
#include "tcpsocket.h"
#include <QDebug>
TCPClient::TCPClient(){
m_ip = "127.0.0.1";
m_port = 60000;
m_tcpsocket = new QTcpSocket();
qDebug()<<"create a default TCP client!";
connect(m_tcpsocket,&QTcpSocket::connected,this,&TCPClient::onConnected,Qt::AutoConnection);
connect(m_tcpsocket,&QTcpSocket::readyRead,this,&TCPClient::getMsg,Qt::AutoConnection);
m_bReceive = false;
}
TCPClient::~TCPClient(){
m_tcpsocket->deleteLater();
}
void TCPClient::setIP(const QString ip){
m_ip = ip;
qDebug()<<"set IP: "<<ip;
}
void TCPClient::setPort(const int port){
m_port = port;
qDebug()<<"set port: "<<port;
}
void TCPClient::onConnected(){
qDebug()<<"already connect the host : "<<m_ip;
}
void TCPClient::closeSocket()
{
m_tcpsocket->close();
}
void TCPClient::getMsg()
{
if( !m_bReceive)
{
m_bReceive =true;
QByteArray buffer;
buffer = m_tcpsocket->readAll();
const char* pData = buffer.data();
memcpy(&m_length,&pData[3],4);
m_message += buffer;
}
m_message += m_tcpsocket->readAll();
int len = m_message.length();
qDebug()<<"len"<<len<<"m_length"<<m_length<<endl;
if(len == m_length)
{
m_bReceive = false;
emit showMsg(m_message);
m_message.clear();
}
else if(len >m_length)
{
emit showMsg(m_message);
m_message += m_message.data()+(len-m_length);
const char* pData = m_message.data();
m_length =0 ;
memcpy(&m_length,&pData[3],4);
while(m_message.length() >= m_length && m_message.length()>0)
{
emit showMsg(m_message);
m_message += m_message.length()-m_length;
const char* pData = m_message.data();
m_length =0 ;
memcpy(&m_length,&pData[3],4);
}
}
}
int TCPClient::createTcpConnect()
{
m_tcpsocket->abort();
m_tcpsocket->connectToHost(m_ip,m_port);
if(!m_tcpsocket->waitForConnected(3000))
{
qDebug() << "Connection failed!";
return 1;
}
return 0;
}
void TCPClient::sendMsg(const QByteArray &data)
{
m_tcpsocket->write(data);
}
以上代码为项目代码 不需要可以自行删除
使用方法 在主cpp中 开启timer线程检测心跳时间是否超时
QTimer *m_time = new QTimer;
connect(m_time, SIGNAL(timeout()), this, SLOT(slot_heart()));
void slform::slot_heart()
{
QDateTime endTime= QDateTime::currentDateTime();
qint64 intervalTime = startDatetime.secsTo(endTime);
if(intervalTime > 15)
{
qDebug()<<"heart time out"<<endl;
m_tcpSocket->closeSocket();
killTimer(m_nTimerID);
int ret = createConnect();
if(!ret)
{
startDatetime = QDateTime::currentDateTime();
m_nTimerID = startTimer(15000);
qDebug()<<"connect sucess !"<<endl;
}
else
{
QThread::sleep(5);
}
}
}
当接收到心跳包startDatetime值重新获取最新时间 然后定时查询是否超时
void slform::recvMsg(const QByteArray &data)
{
// qDebug()<<"recv leng"<<data.length()<<endl;
const char *pMsg = data.data();
int totLen;
memcpy(&totLen,&pMsg[3],4);
unsigned char hNum = pMsg[0];
if (hNum != 0x75)
return;
unsigned char cmd = pMsg[8];
switch (cmd)
{
case 0x00://未定义指令(错误指令)
break;
case 0x88://心跳指令
{
startDatetime = QDateTime::currentDateTime();
break;
}
}