QTcpsocket 使用 模板

来源:互联网 发布:支付宝 api端口号 编辑:程序博客网 时间:2024/05/21 08:38

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">常用代码,在这里记录一下,方便以后查找</span>

客户端

Client.h

ifndef CLIENT_H#define CLIENT_H#include <QObject>#include <QTcpSocket>#include <QTimer>#include <QTime>class Client:public QObject{    Q_OBJECTpublic:Client(QString ip,int port);~Client();void connectServer();void sendCallInfo(QString& info);signals:void message(QString info);protected slots:    void readMessage();    //发送并检测心跳包,判断是否连接状态,断开则重连    void sendAndCheckHeartPacket();void error(QAbstractSocket::SocketError socketError);    void connectToHost();    void disConnectToHost();protected:    QTimer m_timer;  //定时发送心跳包    int m_time;    //用于计时,看没有收到心跳包的秒数    QTcpSocket* m_tcpSocket;    QByteArray m_outBlock;    QString m_ip;    int m_port;    bool m_bConnectToHost;    short m_blockSize;};#endif // CLIENT_H

Client.cpp

#include "client.h"#include <QDebug>#include <QSettings>#include <QDataStream>#include <simplelog.h>Client::Client(QString ip, int port){m_tcpSocket = NULL;m_ip = ip;m_port = port;m_bConnectToHost = false;m_blockSize = 0;    connect(&m_timer,SIGNAL(timeout()),this,SLOT(sendAndCheckHeartPacket()));m_timer.start(1000);m_time = 0; m_blockSize = 0;}Client::~Client(){    m_timer.stop();    if(m_tcpSocket)delete m_tcpSocket;}void Client::connectServer(){    if(m_timer.isActive())m_timer.stop();    if(m_tcpSocket != NULL)    {LOGWRANING(QString::fromLocal8Bit("tcp reconnect!"));        disconnect(m_tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage()));        disconnect(m_tcpSocket,SIGNAL(connected()),this,SLOT(connectToHost()));        disconnect(m_tcpSocket,SIGNAL(disconnected()),this,SLOT(disConnectToHost()));        delete m_tcpSocket;    }    m_tcpSocket = new QTcpSocket(this);    connect(m_tcpSocket,SIGNAL(connected()),this,SLOT(connectToHost()));    connect(m_tcpSocket,SIGNAL(disconnected()),this,SLOT(disConnectToHost()));connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError)));    m_tcpSocket->abort();    m_tcpSocket->connectToHost(m_ip,m_port);    qDebug() << "connect to: " << m_ip << "," << m_port;    connect(m_tcpSocket,SIGNAL(readyRead()),this,SLOT(readMessage()));    m_timer.start(1000);    m_time = 0;    m_blockSize = 0;}void Client::sendCallInfo(QString& info){if (!m_bConnectToHost){qDebug() << "the socket is available\n";return;}QDataStream sendOut(&m_outBlock, QIODevice::WriteOnly);sendOut.setVersion(QDataStream::Qt_4_6);sendOut << (quint16)0;sendOut << uchar(0xFE) << info << uchar(0xAA);sendOut.device()->seek(0);sendOut << (quint16)(m_outBlock.size() - sizeof(quint16));m_tcpSocket->write(m_outBlock);m_outBlock.resize(0);}void Client::connectToHost(){    qDebug() << "success to connect to server\n";    m_bConnectToHost = true;}void Client::disConnectToHost(){    qDebug() << "disconnect from host\n";if (m_tcpSocket){LOGWRANING(QString::fromLocal8Bit("disconnect from host").arg(m_tcpSocket->errorString()));}    m_bConnectToHost = false;}void Client::readMessage(){    QDataStream in(m_tcpSocket);    in.setVersion(QDataStream::Qt_4_6);   // qDebug() << "socket size: " << m_tcpSocket->readBufferSize();    if(m_blockSize==0) //如果是刚开始接收数据    {        //判断接收的数据是否有两字节,也就是文件的大小信息        //如果有则保存到blockSize变量中,没有则返回,继续接收数据        if(m_tcpSocket->bytesAvailable() < (int)sizeof(quint16)) return;        in >> m_blockSize;    }    //如果没有得到全部的数据,则返回,继续接收数据    if(m_tcpSocket->bytesAvailable() < m_blockSize) return;    unsigned char _startFlag;    unsigned char _endFlag;    in >> _startFlag;   // qDebug() << _startFlag << "," << m_tcpSocket->readBufferSize();    if(_startFlag == 0XFF)    {        in >> _endFlag;        if(_endFlag == 0xAA)        {            //if(m_location == _location)qDebug() << "receive heart package,connection is alive";            m_time = 0;//重新开始计时        }    }else if (_startFlag == 0XFE)    {QString info;in >> info;in >> _endFlag;if (_endFlag == 0xAA){emit message(info);}    }    m_blockSize = 0;}void Client::sendAndCheckHeartPacket(){    if(m_time >= 10 || !m_bConnectToHost)//如果40秒钟未收到服务器返回的心跳包,重连    {if (m_tcpSocket){LOGWRANING(QString::fromLocal8Bit("disconnect from host").arg(m_tcpSocket->errorString()));}elseLOGWRANING(QString::fromLocal8Bit("检查到连接断开:time:%1,%2").arg(m_time).arg(m_bConnectToHost));        connectServer();    }    m_time += 1;    if(!m_tcpSocket)return;    if(m_tcpSocket->isValid() && m_bConnectToHost)    {        QDataStream sendOut(&m_outBlock,QIODevice::WriteOnly);        sendOut.setVersion(QDataStream::Qt_4_6);        sendOut<<(quint16) 0;        sendOut << uchar(0xFF) << uchar(0xAA);        sendOut.device()->seek(0);        sendOut<<(quint16) (m_outBlock.size() - sizeof(quint16));        m_tcpSocket->write(m_outBlock);        m_outBlock.resize(0);    }}void Client::error(QAbstractSocket::SocketError socketError){if (m_tcpSocket)LOGERROR(QString::fromLocal8Bit("SOCKET 发生错误:%1,%2").arg(socketError).arg(m_tcpSocket->errorString()));}

服务端

server.h

#ifndef SERVER_H#define SERVER_H#include <QObject>#include <QJsonObject>#include <QTcpServer>#include <QTcpSocket>#include <QTimer>#include <QTime>#include <QSettings>class ClientRef;class Server:public QObject{    Q_OBJECTpublic:Server(int port);~Server(){};public:void sendCallInfo(QString& info);protected slots:    virtual void newConnect();    void destroyConnection(ClientRef* ref);protected:    QTcpServer* m_tcpServer;    QList<ClientRef*> m_connectClients;};class ClientRef : public QObject{    Q_OBJECTpublic:ClientRef(QTcpSocket* socket,Server* _parent);~ClientRef();void sendCallInfo(QString& info);signals:void destroy(ClientRef* ref);public slots:    void readMessage();    //检测心跳包,判断是否连接状态,断开则重连    void checkHeartPacket();    void disConnectSocket();void error(QAbstractSocket::SocketError socketError);protected:friend class Server;    QByteArray m_outBlock;    QTcpSocket* m_tcpSocket;    QTimer m_timer;  //    int m_time;      //用于计时,看多久没有收到心跳包de miaoshu    bool m_bSocketAvailable;    Server* m_parent;    short m_blockSize;};#endif // SERVER_H

server.cpp

#include "server.h"#include <iostream>#include <QDebug>#include <QTime>#include "simplelog.h"#include "persession.h"#include <QDataStream>Server::Server(int port){    m_tcpServer = new QTcpServer(this);    connect(m_tcpServer,SIGNAL(newConnection()),this,SLOT(newConnect())); //新连接信号触发,调用newConnect()槽函数,这个跟信号函数一样,其实你可以随便取}if (m_tcpServer->listen(QHostAddress::Any, port)){LOGINFO(QString::fromLocal8Bit("监听端口%1成功").arg(port));}}void Server::sendCallInfo(QString& info){static PerSession sessionSaved;PerSession& sessionReceived = PerSession::fromPackage(info);if (sessionSaved.callID() == sessionReceived.callID()){if (sessionSaved.endReason() == sessionReceived.endReason()){//保证发送的状态信息是不断向前的if (sessionReceived.findCaller()->curState() <= sessionSaved.findCaller()->curState() && sessionReceived.findFirstCalled()->curState() <= sessionSaved.findFirstCalled()->curState()){return;}}}for (int i = 0; i < m_connectClients.size(); i++){m_connectClients[i]->sendCallInfo(info);}sessionSaved = sessionReceived;}void Server::newConnect(){ClientRef* _cr = new ClientRef(m_tcpServer->nextPendingConnection(),this);connect(_cr, SIGNAL(destroy(ClientRef*)), this, SLOT(destroyConnection(ClientRef*)));    m_connectClients.append(_cr);LOGINFO(QString("new connect comming to :%1").arg(_cr->m_tcpSocket->localAddress().toString()));}void Server::destroyConnection(ClientRef* ref){    if(m_connectClients.contains(ref))    {LOGWRANING(QString::fromLocal8Bit("移除 %1 的连接").arg(ref->m_tcpSocket->localAddress().toString()));        m_connectClients.removeOne(ref);ref->deleteLater();//delete ref;    }}////////////////////////////////////////////////////////////////////////////////////ClientRef::ClientRef(QTcpSocket* socket, Server* _parent){m_tcpSocket = socket;connect(m_tcpSocket, SIGNAL(readyRead()), this, SLOT(readMessage())); //有可读的信息,触发读函数槽connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(disConnectSocket()));connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(&m_timer,SIGNAL(timeout()),SLOT(checkHeartPacket()));     m_blockSize = 0;     m_outBlock.resize(0);     m_parent = _parent;     m_time = 0; m_bSocketAvailable = true; m_timer.start(1000);}ClientRef::~ClientRef(){    m_timer.stop();}void ClientRef::sendCallInfo(QString& info){if (!m_bSocketAvailable){qDebug() << "the socket is available\n";return;}QDataStream sendOut(&m_outBlock, QIODevice::WriteOnly);sendOut.setVersion(QDataStream::Qt_4_6);sendOut << (quint16)0;sendOut << uchar(0xFE) << info << uchar(0xAA);sendOut.device()->seek(0);sendOut << (quint16)(m_outBlock.size() - sizeof(quint16));m_tcpSocket->write(m_outBlock);m_outBlock.resize(0);}void ClientRef::disConnectSocket(){  LOGERROR(m_tcpSocket->localAddress().toString() + " disconnect");    m_bSocketAvailable = false;}void ClientRef::error(QAbstractSocket::SocketError socketError){if (m_tcpSocket)LOGERROR(QString::fromLocal8Bit("SOCKET 发生错误:%1,%2").arg(socketError).arg(m_tcpSocket->errorString()));}void ClientRef::checkHeartPacket(){    if(m_time >= 10 || !m_bSocketAvailable)//如果10秒钟未收到服务器返回的心跳包,重连    { LOGWRANING(QString::fromLocal8Bit("检查到连接断开:time:%1,%2").arg(m_time).arg(m_tcpSocket->errorString()));        emit destroy(this);//删除自身return;    }    m_time += 1;}void ClientRef::readMessage() //读取信息{    QDataStream in(m_tcpSocket);    in.setVersion(QDataStream::Qt_4_6);    if(m_blockSize==0) //如果是刚开始接收数据    {        //判断接收的数据是否有两字节,也就是文件的大小信息        //如果有则保存到blockSize变量中,没有则返回,继续接收数据        if(m_tcpSocket->bytesAvailable() < (int)sizeof(quint16)) return;        in >> m_blockSize;    }    //如果没有得到全部的数据,则返回,继续接收数据    if(m_tcpSocket->bytesAvailable() < m_blockSize) return;    unsigned char _startFlag;    unsigned char _endFlag;    in >> _startFlag;    if(_startFlag == 0XFF)    {        in >> _endFlag;        if(_endFlag == 0xAA)        {            QDataStream sendOut(&m_outBlock,QIODevice::WriteOnly);            sendOut.setVersion(QDataStream::Qt_4_6);            sendOut<<(quint16) 0;            sendOut << uchar(0xFF) << uchar(0xAA);            sendOut.device()->seek(0);            sendOut<<(quint16) (m_outBlock.size() - sizeof(quint16));            m_tcpSocket->write(m_outBlock);            m_outBlock.resize(0);            m_time = 0;        }    }else if (_startFlag == 0XFE)    {QString info;in >> info;in >> _endFlag;if (_endFlag == 0xAA){m_parent->sendCallInfo(info);}    }    m_blockSize = 0;}


</pre><pre>
0 0
原创粉丝点击