server.h
#ifndef SERVERDEMO_H
#define SERVERDEMO_H#include <QObject>
#include <QTcpServer>
#include <QMap>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord> #include "TextMessage.h"
#include "txtmsgassembler.h"
#include "TxtMsgHandler.h"class ServerDemo : public QObject
{Q_OBJECTQTcpServer m_server; QMap<QTcpSocket*, TxtMsgAssembler*> m_map;TxtMsgHandler* m_handler;QSqlDatabase db;
public:ServerDemo(QObject* parent = NULL);bool start(int port); void stop(); void setHandler(TxtMsgHandler* handler);~ServerDemo();protected slots:void onNewConnection(); void onConnected(); void onDisconnected(); void onDataReady(); void onBytesWritten(qint64 bytes);
};#endif
server.cpp
#include "ServerDemo.h"
#include <QHostAddress>
#include <QTcpSocket>
#include <QObjectList>
#include <QDebug>ServerDemo::ServerDemo(QObject* parent) : QObject(parent), m_handler(nullptr)
{if( !db.contains("user.db") ){db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("user.db");}if( !db.open() ){qDebug() << "数据库打开失败" << endl;return;}QString sql = "create table if not exists user_info(""username varchar(16) primary key,""password varchar(16),""status varchar(10),""level varchar(10))";QSqlQuery querry;if( !querry.exec(sql) ){qDebug() << "表创建失败失败" << endl;return;}connect(&m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}void ServerDemo::onNewConnection()
{QTcpSocket* tcp = m_server.nextPendingConnection();TxtMsgAssembler* assembler = new TxtMsgAssembler();m_map.insert(tcp, assembler);connect(tcp, SIGNAL(connected()), this, SLOT(onConnected()));connect(tcp, SIGNAL(disconnected()), this, SLOT(onDisconnected()));connect(tcp, SIGNAL(readyRead()), this, SLOT(onDataReady()));connect(tcp, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));if( m_handler != nullptr ){TextMessage msg("CONN", tcp->peerAddress().toString() + ":" + QString::number(tcp->peerPort()));m_handler->handle(*tcp, msg);}
}void ServerDemo::onConnected()
{}void ServerDemo::onDisconnected()
{QTcpSocket* tcp = dynamic_cast<QTcpSocket*>(sender());if( tcp != nullptr ){delete m_map.take(tcp);if( m_handler != nullptr ){TextMessage msg("DSCN", "");m_handler->handle(*tcp, msg);}}
}
void ServerDemo::onDataReady()
{QTcpSocket* tcp = dynamic_cast<QTcpSocket*>(sender());char buf[256] = {0};int len = 0;if( tcp != NULL ){TxtMsgAssembler* assembler = m_map.value(tcp);while( (len = tcp->read(buf, sizeof(buf))) > 0 ){if( assembler != nullptr ){QSharedPointer<TextMessage> ptm = nullptr;assembler->prepare(buf, len);while( (ptm = assembler->assemble()) != nullptr ){if( m_handler != nullptr ){m_handler->handle(*tcp, *ptm);}}}}}
}void ServerDemo::onBytesWritten(qint64 bytes)
{(void)bytes;
}
bool ServerDemo::start(int port)
{bool ret = true;if( !m_server.isListening() ){ret = m_server.listen(QHostAddress("127.0.0.1"), port);}return ret;
}
void ServerDemo::stop()
{if( m_server.isListening() ){m_server.close();}
}
void ServerDemo::setHandler(TxtMsgHandler *handler)
{m_handler = handler;
}
ServerDemo::~ServerDemo()
{const QObjectList& list = m_server.children();for(int i=0; i<list.length(); i++){QTcpSocket* tcp = dynamic_cast<QTcpSocket*>(list[i]);if( tcp != NULL ){tcp->close();}}const QList<TxtMsgAssembler*>& al = m_map.values();for(int i = 0; i < al.length(); i++){delete al.at(i);}
}
server_main.cpp
#include <QCoreApplication>
#include "serverhandler.h"
#include "ServerDemo.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);ServerHandler handler;ServerDemo server;server.setHandler(&handler);server.start(8888);return a.exec();
}
client.h
#ifndef CLIENTDEMO_H
#define CLIENTDEMO_H#include <QObject>
#include <QTcpSocket>
#include "TextMessage.h"
#include "txtmsgassembler.h"
#include "TxtMsgHandler.h"class ClientDemo : public QObject
{Q_OBJECTQTcpSocket m_client; TxtMsgAssembler m_assembler; TxtMsgHandler* m_handler;
protected slots:void onConnected(); void onDisconnected(); void onDataReady(); void onBytesWritten(qint64 bytes);public:ClientDemo(QObject* parent = NULL);bool connectTo(QString ip, int port); qint64 send(TextMessage& message); qint64 available(); void setHandler(TxtMsgHandler* handler);bool isValid(); void close();
};#endif
client.cpp
#include "ClientDemo.h"
#include <QHostAddress>
#include <QDebug>
ClientDemo::ClientDemo(QObject* parent) : QObject(parent), m_handler(nullptr)
{connect(&m_client, SIGNAL(connected()), this, SLOT(onConnected()));connect(&m_client, SIGNAL(disconnected()), this, SLOT(onDisconnected()));connect(&m_client, SIGNAL(readyRead()), this, SLOT(onDataReady()));connect(&m_client, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
}
void ClientDemo::onConnected()
{if( m_handler != nullptr ){TextMessage conn("CONN", m_client.peerAddress().toString() + ":" + QString::number(m_client.peerPort()));m_handler->handle(m_client, conn);}
}
void ClientDemo::onDisconnected()
{m_assembler.reset(); if( m_handler != nullptr ){TextMessage dscn("DSCN", "");m_handler->handle(m_client, dscn);}
}
void ClientDemo::onDataReady()
{char buf[256] = {0};int len = 0;while( (len = m_client.read(buf, sizeof(buf))) > 0 ){QSharedPointer<TextMessage> ptm = nullptr;m_assembler.prepare(buf, len); while( (ptm = m_assembler.assemble()) != nullptr ){if( m_handler != nullptr ){m_handler->handle(m_client, *ptm);}}}
}void ClientDemo::onBytesWritten(qint64 bytes)
{(void)bytes;
}
bool ClientDemo::connectTo(QString ip, int port)
{m_client.connectToHost(ip, port);return m_client.waitForConnected();
}
qint64 ClientDemo::send(TextMessage& message)
{QByteArray ba = message.serialize();return m_client.write(ba.data(), ba.length());
}
qint64 ClientDemo::available()
{return m_client.bytesAvailable();
}void ClientDemo::setHandler(TxtMsgHandler *handler)
{m_handler = handler;
}
bool ClientDemo::isValid()
{return m_client.isValid();
}
void ClientDemo::close()
{m_client.close();
}
client_main.cpp
#include "MainwinUI.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWin w;w.show();return a.exec();
}
阶段性效果图