qt qtcpserver编程入门
来源:互联网 发布:2016年5月非农数据 编辑:程序博客网 时间:2024/05/17 03:22
代码 :
1 连接成功后每个连接创建一个处理对象 cclientSession,
2 所有cclientSession对象的slot 都在另外一个线程中处理,即处理方式为创建一个线程处理所有客户端连接
3 大文件传输需要自己用协议分片
#ifndef QNETCONTRLSERVER_H#define QNETCONTRLSERVER_H#include <QObject>#include <QTcpServer>#include <QTcpSocket>#include <QThread>#include <QDebug>//通信模式 [命令id(4byte)+数据长度(4bytes)+数据(n bytes)]#define CMD_ID_ALLINFO 1class CClientSession:public QObject{Q_OBJECTpublic:CClientSession(QObject* parent = NULL);~CClientSession();public slots:void onNewDescriptor(qintptr desc);void onSocketErr(QAbstractSocket::SocketError err);void onReadDataReady();void onResponse(QByteArray sndData);//void onWriteDataReady();signals:void newDescriptor(qintptr handle);void cmdPacket(CClientSession* client,int id, QByteArray data);void cmdResponse(QByteArray sndData);protected:void decodePacket();private:QTcpSocket* m_tcpClient;QByteArray m_cmdPacketTemp;};class QNetContrlServer : public QTcpServer{Q_OBJECTpublic:QNetContrlServer(QObject *parent = NULL);virtual ~QNetContrlServer();public slots://void onNewConnection(qintptr descriptor);protected:virtual void incomingConnection(qintptr handle);private:QThread* m_workThread; };
#include "qnetcontrlserver.h"#include "mainwindow.h"CClientSession::CClientSession(QObject* parent):QObject(parent){connect(this,SIGNAL(newDescriptor(qintptr)),this,SLOT(onNewDescriptor(qintptr)));connect(this,SIGNAL(cmdResponse(QByteArray )),this,SLOT(onResponse(QByteArray)));}CClientSession::~CClientSession(){}void CClientSession::onSocketErr(QAbstractSocket::SocketError err){qDebug()<<"onSocketErr: "<<QThread::currentThreadId() << " socket error: "<<err; m_tcpClient->disconnectFromHost();}void CClientSession::onNewDescriptor(qintptr desc){qDebug()<<"onNewDescriptor: "<<QThread::currentThreadId() << "new descriptor: "<<desc;; m_tcpClient = new QTcpSocket();if (!m_tcpClient->setSocketDescriptor(desc)){return;}connect(m_tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onSocketErr(QAbstractSocket::SocketError)));connect(m_tcpClient,SIGNAL(disconnected()),m_tcpClient,SLOT(deleteLater()));connect(m_tcpClient,SIGNAL(readyRead()),this,SLOT(onReadDataReady()));}void CClientSession::onReadDataReady(){qDebug()<<"onReadDataReady: "<<QThread::currentThreadId(); qint64 bytes = m_tcpClient->bytesAvailable();if (bytes > 0){QByteArray buffer = m_tcpClient->read(bytes);qDebug()<<buffer.toHex();m_cmdPacketTemp.append(buffer);decodePacket();}}void CClientSession::decodePacket(){while(m_cmdPacketTemp.size() >= 8) //允许客户端一次发送多个命令{qint32* ptr = (int*)m_cmdPacketTemp.data();int cmdId = *ptr++;int cmdSize = *ptr;if (m_cmdPacketTemp.size() -8 >= cmdSize ){QByteArray data ;data.append(m_cmdPacketTemp.data()+8,cmdSize);emit cmdPacket(this,cmdId,data);m_cmdPacketTemp.remove(0,cmdSize+8);qDebug()<<"command id: "<<cmdId<<" data size: "<<cmdSize <<"data: "<< data.toHex();}else{break;}}return;}void CClientSession::onResponse(QByteArray sndData){if(sndData.size() > 0){qint64 sndSize = m_tcpClient->write(sndData);if(!m_tcpClient->waitForBytesWritten()) //大文件传输请自定义协议分片传输,以免阻塞线程{m_tcpClient->disconnectFromHost();}}//delete sndData;}////////////////////////////////////////////////////////////////////////////QNetContrlServer//////////////////////////////////////////////////////////////////////////QNetContrlServer::QNetContrlServer(QObject *parent): QTcpServer(parent){qRegisterMetaType<QAbstractSocket::SocketError>("SocketError");qRegisterMetaType<qintptr>("qintptr");m_workThread = new QThread();connect(m_workThread,SIGNAL(finished()),m_workThread,SLOT(deleteLater()));m_workThread->start();if(!listen(QHostAddress::Any,999)){}}QNetContrlServer::~QNetContrlServer(){}void QNetContrlServer::incomingConnection(qintptr descriptor){qDebug()<<"incomingConnection: "<<QThread::currentThreadId() << "new descriptor: "<<descriptor;CClientSession* session = new CClientSession();//connect(session,SIGNAL(newDescriptor(qintptr)),session,SLOT(onNewDescriptor(qintptr)));session->moveToThread(m_workThread);emit session->newDescriptor(descriptor);//session->onNewDescriptor(descriptor);MainWindow* qMainWin = (MainWindow*)this->parent();connect(session,SIGNAL(cmdPacket(CClientSession* ,int , QByteArray )),qMainWin,SLOT(onCmdHandle(CClientSession* ,int , QByteArray )));}
0 0
- qt qtcpserver编程入门
- Qt QTcpServer
- Qt网络编程QTcpServer和QTcpSocket的理解
- Qt网络编程QTcpServer和QTcpSocket的理解
- Qt QTcpServer的使用
- Qt QTcpServer/QTcpSocke
- qt之QTcpServer
- Qt中QTcpServer多线程误区
- QTcpServer
- QT编程入门
- QT编程入门
- qt编程入门
- QT编程初步入门
- 【Qt编程】- 入门
- qt quick 入门编程
- qt界面编程入门
- QT自带QTcpServer架构分析
- QT自带QTcpServer架构分析
- EventBus使用详解(二)——EventBus使用进阶
- LeetCode之Remove Duplicates from Sorted Array
- android之ConnectivityManager简介,网络连接状态
- jmeter测试TCP服务器/模拟发送TCP请求
- google面试准备
- qt qtcpserver编程入门
- 哈希表之bkdrhash算法解析及扩展
- 迷宫代码
- 七牛云存储用户怎样自己自己分析网络状况,并提供有效信息给七牛技术支持
- 为什么用freemarker而不用jsp
- C/C++ STACK &HEAP 区别
- CodeForces 3D. Least Cost Bracket Sequence
- Python图形图像处理库的介绍之Image模块.
- 新浪微博OAUTH2.0授权验证(基于SSO客户端验证)