1、头文件
#ifndef TCPCLIENT_H #define TCPCLIENT_H #include <QTcpSocket> class TcpClient : public QObject { Q_OBJECT public: TcpClient(QObject *parent); ~TcpClient(); private: QTcpSocket* tcpClient = NULL;//tcp客户端
private slots: void openSlot(QString ipStr,quint16 port);//连接服务器槽函数 void rcvSlot();//接收数据槽函数 void sendSlot(QByteArray ba);//发送数据槽函数 void closeSlot();//关闭连接槽函数 void tcpStateChangeSlot(QAbstractSocket::SocketState socketState);//TCP状态变化槽函数 signals: void tcpStateSignal(QString info);//向外发出的调试信息 void tcpConnectSignal(bool ok);//连接成功信号 void getPacketSignal(int type, QByteArray ba);//tcp将不同的包发出去 }; #endif // TCPCLIENT_H
2、源文件
#include "tcpclient.h" #pragma execution_character_set("utf-8") TcpClient::TcpClient(QObject *parent) : QObject(parent) { } TcpClient::~TcpClient() { } /*****************************************************************/ //作者:朱小勇 //函数名称:连接服务器槽函数 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void TcpClient::openSlot(QString ipStr, quint16 port) { if (NULL == tcpClient) { tcpClient = new QTcpSocket(); QObject::connect(this->tcpClient, SIGNAL(readyRead()), this, SLOT(rcvSlot()));//接收数据信号槽 QObject::connect(tcpClient, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(tcpStateChangeSlot(QAbstractSocket::SocketState)));//状态变化信号槽 }if (tcpClient->isOpen()) { return; } tcpClient->connectToHost(ipStr, port);//连接服务器 } /*****************************************************************/ //作者:朱小勇 //函数名称:接收数据槽函数 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void TcpClient::rcvSlot() { static QByteArray allBa;//用来存所有文件 allBa.append(tcpClient->readAll());//读取数据 int head = allBa.indexOf(HEAD);//报文头的位置 uint16_t length = 0;//存长度字节 QByteArray currentBa; int id = 0; while (-1 != head) { allBa = allBa.mid(head);//去掉报头之前的 memcpy(&length, allBa.data() + 2, 2); if (allBa.size() >= length)//长度够,进行解析 { currentBa = allBa.mid(0, length);//获取当前完成包 id = Mymethod::getPacketType(currentBa); if (-1 != id) { emit getPacketSignal(id, currentBa); qDebug() << "接收指令:" << currentBa.toHex().toUpper(); } allBa = allBa.mid(2); } else { break; } head = allBa.indexOf(HEAD);//刷新报文头的位置 } } /*****************************************************************/ //作者:朱小勇 //函数名称:关闭连接 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void TcpClient::closeSlot() { if (NULL != tcpClient) tcpClient->close(); } /*****************************************************************/ //作者:朱小勇 //函数名称:发送数据 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void TcpClient::sendSlot(QByteArray ba) { if ((NULL == tcpClient) || (!tcpClient->isOpen())) { emit tcpStateSignal("未连接至服务器,发送请求失败!!!"); return; } if (ba.size() != tcpClient->write(ba)) { emit tcpStateSignal("发送请求失败!!!"); } else { emit tcpStateSignal("成功发送请求..."); } } /*****************************************************************/ //作者:朱小勇 //函数名称:状态变化槽函数 //函数参数:NULL //函数返回值:NULL //函数作用:NULL //备注:NULL /*****************************************************************/ void TcpClient::tcpStateChangeSlot(QAbstractSocket::SocketState socketState) { if (QAbstractSocket::ConnectedState == socketState) { emit tcpStateSignal("成功连接至服务器..."); emit tcpConnectSignal(true); } else if (QAbstractSocket::ConnectingState == socketState) { emit tcpStateSignal("正在寻找服务器..."); } else if (QAbstractSocket::UnconnectedState == socketState) { emit tcpStateSignal("断开连接!!!"); emit tcpConnectSignal(false); } }