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
- QTcpsocket 使用 模板
- 使用QTcpSocket接收数据
- QTcpServer+QTcpSocket使用整理
- QTcpSocket
- QTcpsocket
- QUdpSocket和QTcpSocket的使用
- QT5使用QTcpSocket类注意事项
- QTcpServer和QTcpSocket的使用
- Qt5.2 使用qtcpsocket 传送消息
- QTcpSocket使用过程中的一些问题记录
- 使用QTcpSocket和QTcpServer进行TCP编程
- 关于使用QTcpSocket的一些总结
- QTcpSocket使用过程中的一些问题记录
- QTcpSocket使用过程中的一些问题记录
- 关于使用QTcpSocket的一些总结
- QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端
- QTcpServer使用多线程处理连接进来的QTcpSocket
- QTcpSocket 编程
- sqlserver 死锁
- Docker如何build Tomcat镜像
- Android——第三方登录——新浪微博——获取用户信息——账户绑定
- 来自中午机房的1071
- C语言笔记系列(一)--概述
- QTcpsocket 使用 模板
- java工具类之对象与字节数组之间的互相转换
- php代码优化
- Hibernate中操作managed/persistent状态的Entity对象使之成为detached状态的Entity对象
- 文章标题
- ios 判断字符串为空和只为空格解决办法
- 高精度乘方二
- 剑指offer-面试题22:栈的压入,弹出序列
- win10 驱动程序无法使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:Could not generate DH keypair