Qt TCP Client
2018年07月16日 18:22:03 五香花生米 閱讀數:314
版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/aristolto/article/details/81069492
頭文件tcpclient.h
-
#ifndef TCPCLIENT_H
-
#define TCPCLIENT_H
-
#include <QObject>
-
#include <QTcpSocket>
-
#include <QDebug>
-
#include "enthernetdataparsing.h"
-
#include "tf500enthernetdataparsing.h"
-
class TCPClient : public QObject
-
{
-
Q_OBJECT
-
public:
-
explicit TCPClient(QObject *parent = 0);
-
signals:
-
void reConnect();
-
public slots:
-
void slot_connectServer(QString serverIP, quint16 port);
-
void slot_reConnectServer();
-
private slots:
-
void processError(QAbstractSocket::SocketError socketError);
-
void readData();
-
qint64 writeData(const char * data, qint64 len);
-
void hostFound();
-
void connected();
-
private:
-
QTcpSocket *tcpSocket;
-
QString serverIP;
-
quint16 port;
-
char *recvBuf;
-
EnthernetDataParsing *enthernetDataParsing;
-
private:
-
void reConnectServer();
-
void allocMemory();
-
void disconnectFromServer();
-
public:
-
void connectServer(QString serverIP, quint16 port);
-
};
-
#endif // TCPCLIENT_H
.cpp
-
#include <QThread>
-
#include <QtEndian>
-
#include <syslog.h>
-
#include "tcpclient.h"
-
#include "printfhex.h"
-
TCPClient::TCPClient(QObject *parent) :
-
QObject(parent)
-
{
-
tcpSocket = new QTcpSocket(this);
-
tcpSocket->setReadBufferSize(32 * 1024);
-
enthernetDataParsing = new TF500EnthernetDataParsing();
-
recvBuf = NULL;
-
allocMemory();
-
connect(enthernetDataParsing, SIGNAL(writeData(const char*,qint64)),
-
this, SLOT(writeData(const char*,qint64)));
-
connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
-
this, SLOT(processError(QAbstractSocket::SocketError)));
-
connect(tcpSocket, SIGNAL(hostFound()), this, SLOT(hostFound()));
-
connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));
-
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));
-
connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(slot_reConnectServer()));
-
connect(this, SIGNAL(reConnect()), this, SLOT(slot_reConnectServer()));
-
}
-
void TCPClient::allocMemory()
-
{
-
if(!recvBuf){
-
recvBuf = new char[MAX_RECVBUF_LEN];
-
memset(recvBuf, 0, MAX_RECVBUF_LEN);
-
}
-
if(!recvBuf)
-
{
-
qDebug("Alloc Memory error in File:%s Line:%d.", __FILE__, __LINE__);
-
syslog(LOG_ERR | LOG_USER, "Alloc Memory error in File:%s Line:%d.", __FILE__, __LINE__);
-
}
-
}
-
void TCPClient::disconnectFromServer()
-
{
-
tcpSocket->disconnectFromHost();
-
bool ret = tcpSocket->waitForDisconnected(5000);
-
qDebug() << "disconnectFromHost: " << ret;
-
}
-
void TCPClient::slot_connectServer(QString serverIP, quint16 port)
-
{
-
connectServer(serverIP, port);
-
}
-
void TCPClient::slot_reConnectServer()
-
{
-
reConnectServer();
-
}
-
void TCPClient::processError(QAbstractSocket::SocketError socketError)
-
{
-
switch(socketError){
-
case QAbstractSocket::ConnectionRefusedError:
-
qDebug() << tr("The connection was refused by the peer (or timed out).");
-
emit reConnect();
-
break;
-
case QAbstractSocket::RemoteHostClosedError:
-
qDebug() << tr("Remote host closed the connection.");
-
break;
-
case QAbstractSocket::HostNotFoundError:
-
qDebug() << tr("The host was not found. Please check the host name and port settings.");
-
break;
-
// case QAbstractSocket::SocketAccessError:
-
// break;
-
// case QAbstractSocket::SocketResourceError:
-
// break;
-
// case QAbstractSocket::SocketTimeoutError:
-
// break;
-
// case QAbstractSocket::DatagramTooLargeError:
-
// break;
-
case QAbstractSocket::NetworkError: //e.g., the network cable was accidentally plugged out
-
qDebug() << tr("An error occurred with the network.");
-
emit reConnect();
-
break;
-
// case QAbstractSocket::UnsupportedSocketOperationError:
-
// break;
-
default:
-
qDebug() << tr("The following error occurred: %1.").arg(tcpSocket->errorString());
-
break;
-
}
-
}
-
void TCPClient::readData()
-
{
-
int recvLen = 0, onceRecvLen = 0;
-
while(1){
-
if(recvLen < FRAME_HEAD_LEN){
-
onceRecvLen = tcpSocket->read(recvBuf + recvLen, FRAME_HEAD_LEN - recvLen);
-
if(onceRecvLen == -1){
-
tcpSocket->close();
-
break;
-
}
-
recvLen += onceRecvLen;
-
}
-
else{
-
int frameLen = 0;
-
memcpy(&frameLen, recvBuf + START_FRAME_LEN, 4);
-
frameLen = qToBigEndian(frameLen);
-
if(recvLen < frameLen){
-
onceRecvLen = tcpSocket->read(recvBuf + recvLen, frameLen - recvLen);
-
if(onceRecvLen == -1){
-
tcpSocket->close();
-
break;
-
}
-
recvLen += onceRecvLen;
-
}
-
else if(recvLen == frameLen){
-
PrintfHex printfHex;
-
printf("Receive data:");
-
printfHex.printfHex(recvBuf, FRAME_HEAD_LEN, true);
-
//process
-
enthernetDataParsing->parseData(recvBuf, recvLen);
-
break;
-
}
-
else{
-
tcpSocket->readAll();
-
break;
-
}
-
}
-
}
-
qDebug() << "readBytes:" << recvLen;
-
qDebug() << "readData in thread:" << QThread::currentThread();
-
}
-
qint64 TCPClient::writeData(const char *data, qint64 len)
-
{
-
qDebug() << "write data in TCPClient.";
-
qint64 onceWriteLen = 0, sendLen = 0;
-
// onceWriteLen = tcpSocket->write(data + onceWriteLen, len - onceWriteLen);
-
}
-
void TCPClient::hostFound()
-
{
-
qDebug() << "Host found success.";
-
}
-
void TCPClient::connected()
-
{
-
qDebug() << QString("Connect to ip:%1 port:%2 success.").arg(serverIP).arg(port);
-
}
-
void TCPClient::connectServer(QString serverIP, quint16 port)
-
{
-
this->serverIP = serverIP;
-
this->port = port;
-
tcpSocket->connectToHost(serverIP, port);
-
tcpSocket->waitForConnected(5000);
-
}
-
void TCPClient::reConnectServer()
-
{
-
sleep(2);
-
tcpSocket->connectToHost(serverIP, port);
-
tcpSocket->waitForConnected(5000);
-
}
Printfhex是一個打印char數組的類,以16進制打印。
EnthernetDataParsing是一個純虛類,解析收到的數據,源碼如下:
-
#ifndef ENTHERNETDATAPARSING_H
-
#define ENTHERNETDATAPARSING_H
-
#include <QObject>
-
class EnthernetDataParsing : public QObject
-
{
-
Q_OBJECT
-
public:
-
explicit EnthernetDataParsing(QObject *parent = 0);
-
signals:
-
void writeData(const char * data, qint64 len);
-
public slots:
-
public:
-
virtual int parseData(char *data, qint64 len) = 0;
-
};
-
#endif // ENTHERNETDATAPARSING_H
TF500EnthernetDataParsing繼承自EnthernetDataParsing,是按照具體協議解析數據的類。
解析出命令後調用完成對應業務的類,執行完成後發送執行結果。
一般會把TCPClient放到線程中執行:
-
#include <QtCore/QCoreApplication>
-
#include <QThread>
-
#include "tcpclient.h"
-
#include "tcpclientop.h"
-
int main(int argc, char *argv[])
-
{
-
QCoreApplication a(argc, argv);
-
TCPClient tcpClient;
-
TCPClientOP tcpClientOP;
-
QThread thread;
-
tcpClient.moveToThread(&thread);
-
QObject::connect(&tcpClientOP, SIGNAL(connectServer(QString,quint16)),
-
&tcpClient, SLOT(slot_connectServer(QString,quint16)));
-
thread.start();
-
tcpClientOP.startConnect("10.0.10.55", 11866);
-
qDebug() << "main thread:" << QThread::currentThread();
-
return a.exec();
-
}
TCPClientOP
-
#ifndef TCPCLIENTOP_H
-
#define TCPCLIENTOP_H
-
#include <QObject>
-
class TCPClientOP : public QObject
-
{
-
Q_OBJECT
-
public:
-
explicit TCPClientOP(QObject *parent = 0):QObject(parent){};
-
signals:
-
void connectServer(QString serverIP, quint16 port);
-
public slots:
-
public:
-
void startConnect(QString serverIP, quint16 port)
-
{
-
emit connectServer(serverIP, port);
-
}
-
};
-
#endif // TCPCLIENTOP_H