Qt TCP Client 分離

Qt TCP Client

2018年07月16日 18:22:03 五香花生米 閱讀數:314

 版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/aristolto/article/details/81069492

頭文件tcpclient.h


 
  1. #ifndef TCPCLIENT_H

  2. #define TCPCLIENT_H

  3.  
  4. #include <QObject>

  5. #include <QTcpSocket>

  6. #include <QDebug>

  7. #include "enthernetdataparsing.h"

  8. #include "tf500enthernetdataparsing.h"

  9.  
  10. class TCPClient : public QObject

  11. {

  12. Q_OBJECT

  13. public:

  14. explicit TCPClient(QObject *parent = 0);

  15.  
  16. signals:

  17. void reConnect();

  18.  
  19. public slots:

  20. void slot_connectServer(QString serverIP, quint16 port);

  21.  
  22. void slot_reConnectServer();

  23.  
  24. private slots:

  25. void processError(QAbstractSocket::SocketError socketError);

  26.  
  27. void readData();

  28.  
  29. qint64 writeData(const char * data, qint64 len);

  30.  
  31. void hostFound();

  32.  
  33. void connected();

  34.  
  35. private:

  36. QTcpSocket *tcpSocket;

  37.  
  38. QString serverIP;

  39.  
  40. quint16 port;

  41.  
  42. char *recvBuf;

  43.  
  44. EnthernetDataParsing *enthernetDataParsing;

  45.  
  46. private:

  47. void reConnectServer();

  48.  
  49. void allocMemory();

  50.  
  51. void disconnectFromServer();

  52.  
  53. public:

  54. void connectServer(QString serverIP, quint16 port);

  55.  
  56. };

  57.  
  58. #endif // TCPCLIENT_H

.cpp


 
  1. #include <QThread>

  2. #include <QtEndian>

  3. #include <syslog.h>

  4. #include "tcpclient.h"

  5. #include "printfhex.h"

  6.  
  7. TCPClient::TCPClient(QObject *parent) :

  8. QObject(parent)

  9. {

  10. tcpSocket = new QTcpSocket(this);

  11. tcpSocket->setReadBufferSize(32 * 1024);

  12.  
  13. enthernetDataParsing = new TF500EnthernetDataParsing();

  14.  
  15. recvBuf = NULL;

  16. allocMemory();

  17.  
  18. connect(enthernetDataParsing, SIGNAL(writeData(const char*,qint64)),

  19. this, SLOT(writeData(const char*,qint64)));

  20.  
  21. connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),

  22. this, SLOT(processError(QAbstractSocket::SocketError)));

  23.  
  24. connect(tcpSocket, SIGNAL(hostFound()), this, SLOT(hostFound()));

  25.  
  26. connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));

  27.  
  28. connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));

  29.  
  30. connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(slot_reConnectServer()));

  31.  
  32. connect(this, SIGNAL(reConnect()), this, SLOT(slot_reConnectServer()));

  33. }

  34.  
  35. void TCPClient::allocMemory()

  36. {

  37. if(!recvBuf){

  38. recvBuf = new char[MAX_RECVBUF_LEN];

  39. memset(recvBuf, 0, MAX_RECVBUF_LEN);

  40. }

  41.  
  42. if(!recvBuf)

  43. {

  44. qDebug("Alloc Memory error in File:%s Line:%d.", __FILE__, __LINE__);

  45. syslog(LOG_ERR | LOG_USER, "Alloc Memory error in File:%s Line:%d.", __FILE__, __LINE__);

  46. }

  47. }

  48.  
  49. void TCPClient::disconnectFromServer()

  50. {

  51. tcpSocket->disconnectFromHost();

  52. bool ret = tcpSocket->waitForDisconnected(5000);

  53. qDebug() << "disconnectFromHost: " << ret;

  54. }

  55.  
  56. void TCPClient::slot_connectServer(QString serverIP, quint16 port)

  57. {

  58. connectServer(serverIP, port);

  59. }

  60.  
  61. void TCPClient::slot_reConnectServer()

  62. {

  63. reConnectServer();

  64. }

  65.  
  66. void TCPClient::processError(QAbstractSocket::SocketError socketError)

  67. {

  68. switch(socketError){

  69. case QAbstractSocket::ConnectionRefusedError:

  70. qDebug() << tr("The connection was refused by the peer (or timed out).");

  71. emit reConnect();

  72. break;

  73. case QAbstractSocket::RemoteHostClosedError:

  74. qDebug() << tr("Remote host closed the connection.");

  75. break;

  76. case QAbstractSocket::HostNotFoundError:

  77. qDebug() << tr("The host was not found. Please check the host name and port settings.");

  78. break;

  79. // case QAbstractSocket::SocketAccessError:

  80. // break;

  81. // case QAbstractSocket::SocketResourceError:

  82. // break;

  83. // case QAbstractSocket::SocketTimeoutError:

  84. // break;

  85. // case QAbstractSocket::DatagramTooLargeError:

  86. // break;

  87. case QAbstractSocket::NetworkError: //e.g., the network cable was accidentally plugged out

  88. qDebug() << tr("An error occurred with the network.");

  89. emit reConnect();

  90. break;

  91. // case QAbstractSocket::UnsupportedSocketOperationError:

  92. // break;

  93. default:

  94. qDebug() << tr("The following error occurred: %1.").arg(tcpSocket->errorString());

  95. break;

  96. }

  97. }

  98.  
  99. void TCPClient::readData()

  100. {

  101. int recvLen = 0, onceRecvLen = 0;

  102.  
  103. while(1){

  104. if(recvLen < FRAME_HEAD_LEN){

  105. onceRecvLen = tcpSocket->read(recvBuf + recvLen, FRAME_HEAD_LEN - recvLen);

  106. if(onceRecvLen == -1){

  107. tcpSocket->close();

  108. break;

  109. }

  110. recvLen += onceRecvLen;

  111. }

  112. else{

  113. int frameLen = 0;

  114. memcpy(&frameLen, recvBuf + START_FRAME_LEN, 4);

  115. frameLen = qToBigEndian(frameLen);

  116.  
  117. if(recvLen < frameLen){

  118. onceRecvLen = tcpSocket->read(recvBuf + recvLen, frameLen - recvLen);

  119. if(onceRecvLen == -1){

  120. tcpSocket->close();

  121. break;

  122. }

  123. recvLen += onceRecvLen;

  124. }

  125. else if(recvLen == frameLen){

  126. PrintfHex printfHex;

  127. printf("Receive data:");

  128. printfHex.printfHex(recvBuf, FRAME_HEAD_LEN, true);

  129. //process

  130. enthernetDataParsing->parseData(recvBuf, recvLen);

  131. break;

  132. }

  133. else{

  134. tcpSocket->readAll();

  135. break;

  136. }

  137. }

  138. }

  139.  
  140. qDebug() << "readBytes:" << recvLen;

  141. qDebug() << "readData in thread:" << QThread::currentThread();

  142. }

  143.  
  144. qint64 TCPClient::writeData(const char *data, qint64 len)

  145. {

  146. qDebug() << "write data in TCPClient.";

  147.  
  148. qint64 onceWriteLen = 0, sendLen = 0;

  149.  
  150. // onceWriteLen = tcpSocket->write(data + onceWriteLen, len - onceWriteLen);

  151. }

  152.  
  153. void TCPClient::hostFound()

  154. {

  155. qDebug() << "Host found success.";

  156. }

  157.  
  158. void TCPClient::connected()

  159. {

  160. qDebug() << QString("Connect to ip:%1 port:%2 success.").arg(serverIP).arg(port);

  161. }

  162.  
  163. void TCPClient::connectServer(QString serverIP, quint16 port)

  164. {

  165. this->serverIP = serverIP;

  166. this->port = port;

  167. tcpSocket->connectToHost(serverIP, port);

  168. tcpSocket->waitForConnected(5000);

  169. }

  170.  
  171. void TCPClient::reConnectServer()

  172. {

  173. sleep(2);

  174. tcpSocket->connectToHost(serverIP, port);

  175. tcpSocket->waitForConnected(5000);

  176. }

Printfhex是一個打印char數組的類,以16進制打印。

EnthernetDataParsing是一個純虛類,解析收到的數據,源碼如下:


 
  1. #ifndef ENTHERNETDATAPARSING_H

  2. #define ENTHERNETDATAPARSING_H

  3.  
  4. #include <QObject>

  5.  
  6. class EnthernetDataParsing : public QObject

  7. {

  8. Q_OBJECT

  9. public:

  10. explicit EnthernetDataParsing(QObject *parent = 0);

  11.  
  12. signals:

  13. void writeData(const char * data, qint64 len);

  14.  
  15. public slots:

  16.  
  17. public:

  18. virtual int parseData(char *data, qint64 len) = 0;

  19.  
  20. };

  21.  
  22. #endif // ENTHERNETDATAPARSING_H

TF500EnthernetDataParsing繼承自EnthernetDataParsing,是按照具體協議解析數據的類。

解析出命令後調用完成對應業務的類,執行完成後發送執行結果。

一般會把TCPClient放到線程中執行:


 
  1. #include <QtCore/QCoreApplication>

  2. #include <QThread>

  3. #include "tcpclient.h"

  4. #include "tcpclientop.h"

  5.  
  6. int main(int argc, char *argv[])

  7. {

  8. QCoreApplication a(argc, argv);

  9.  
  10. TCPClient tcpClient;

  11. TCPClientOP tcpClientOP;

  12.  
  13. QThread thread;

  14. tcpClient.moveToThread(&thread);

  15. QObject::connect(&tcpClientOP, SIGNAL(connectServer(QString,quint16)),

  16. &tcpClient, SLOT(slot_connectServer(QString,quint16)));

  17. thread.start();

  18.  
  19. tcpClientOP.startConnect("10.0.10.55", 11866);

  20.  
  21. qDebug() << "main thread:" << QThread::currentThread();

  22.  
  23. return a.exec();

  24. }

TCPClientOP


 
  1. #ifndef TCPCLIENTOP_H

  2. #define TCPCLIENTOP_H

  3.  
  4. #include <QObject>

  5.  
  6. class TCPClientOP : public QObject

  7. {

  8. Q_OBJECT

  9. public:

  10. explicit TCPClientOP(QObject *parent = 0):QObject(parent){};

  11.  
  12. signals:

  13. void connectServer(QString serverIP, quint16 port);

  14.  
  15. public slots:

  16.  
  17. public:

  18. void startConnect(QString serverIP, quint16 port)

  19. {

  20. emit connectServer(serverIP, port);

  21. }

  22.  
  23. };

  24.  
  25. #endif // TCPCLIENTOP_H

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章