qt qtcpserver 프로그래밍 입문
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 1
class CClientSession:public QObject
{
Q_OBJECT
public:
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_OBJECT
public:
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 )));
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.