From 2992ccd00dc49143c5c2a81bd8ff78fb6ca98349 Mon Sep 17 00:00:00 2001
From: Msy-msu <2200456405@qq.com>
Date: Thu, 5 Jan 2023 19:50:19 +0800
Subject: [PATCH] first commit
---
TcpServer.pro | 27 +++
TcpServer.pro.user | 430 +++++++++++++++++++++++++++++++++++++++++++++
database.cpp | 169 ++++++++++++++++++
database.h | 32 ++++
datamanager.cpp | 23 +++
datamanager.h | 28 +++
main.cpp | 10 ++
protocol.cpp | 152 ++++++++++++++++
protocol.h | 60 +++++++
tcpserver.cpp | 124 +++++++++++++
tcpserver.h | 38 ++++
11 files changed, 1093 insertions(+)
create mode 100644 TcpServer.pro
create mode 100644 TcpServer.pro.user
create mode 100644 database.cpp
create mode 100644 database.h
create mode 100644 datamanager.cpp
create mode 100644 datamanager.h
create mode 100644 main.cpp
create mode 100644 protocol.cpp
create mode 100644 protocol.h
create mode 100644 tcpserver.cpp
create mode 100644 tcpserver.h
diff --git a/TcpServer.pro b/TcpServer.pro
new file mode 100644
index 0000000..445e20d
--- /dev/null
+++ b/TcpServer.pro
@@ -0,0 +1,27 @@
+QT += core gui network sql
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+CONFIG += c++11
+
+# You can make your code fail to compile if it uses deprecated APIs.
+# In order to do so, uncomment the following line.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ database.cpp \
+ datamanager.cpp \
+ main.cpp \
+ protocol.cpp \
+ tcpserver.cpp
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+HEADERS += \
+ database.h \
+ datamanager.h \
+ protocol.h \
+ tcpserver.h
diff --git a/TcpServer.pro.user b/TcpServer.pro.user
new file mode 100644
index 0000000..93f1308
--- /dev/null
+++ b/TcpServer.pro.user
@@ -0,0 +1,430 @@
+
+
+
+
+
+ EnvironmentId
+ {d3fed20c-1c94-44fc-8f6a-4dbf39b54775}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ false
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ false
+ 1
+ true
+ true
+ true
+ *.md, *.MD, Makefile
+ false
+ true
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+ true
+ false
+ true
+ true
+ true
+ true
+
+
+ 0
+ true
+
+ -fno-delayed-template-parsing
+
+ true
+ Builtin.BuildSystem
+
+ true
+ true
+ Builtin.DefaultTidyAndClazy
+ 4
+
+
+
+ true
+
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop
+ Desktop Qt 6.2.3 MSVC2019 64bit
+ Desktop Qt 6.2.3 MSVC2019 64bit
+ qt.qt6.623.win64_msvc2019_64_kit
+ 0
+ 0
+ 0
+
+ 0
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Debug
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Debug
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+
+
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Release
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Release
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+
+
+ 0
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Profile
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Profile
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+ 0
+
+ 3
+
+
+ 0
+ Deploy
+ Deploy
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+
+ false
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+ true
+ true
+ true
+
+ 2
+
+ Qt4ProjectManager.Qt4RunConfiguration:C:/Users/25761/Desktop/TcpServer/TcpServer.pro
+ C:/Users/25761/Desktop/TcpServer/TcpServer.pro
+ false
+ true
+ true
+ false
+ true
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MSVC2019_64bit-Debug
+
+ 1
+
+
+
+ ProjectExplorer.Project.Target.1
+
+ Desktop
+ Desktop Qt 6.2.3 MinGW 64-bit
+ Desktop Qt 6.2.3 MinGW 64-bit
+ qt.qt6.623.win64_mingw_kit
+ 0
+ 0
+ 0
+
+ 0
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Debug
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Debug
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Debug
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 2
+
+
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Release
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Release
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Release
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+
+
+ 0
+ C:\Users\25761\Desktop\build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Profile
+ C:/Users/25761/Desktop/build-TcpServer-Desktop_Qt_6_2_3_MinGW_64_bit-Profile
+
+
+ true
+ QtProjectManager.QMakeBuildStep
+ false
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+
+ 2
+ Build
+ Build
+ ProjectExplorer.BuildSteps.Build
+
+
+
+ true
+ Qt4ProjectManager.MakeStep
+ clean
+
+ 1
+ Clean
+ Clean
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ false
+
+ Profile
+ Qt4ProjectManager.Qt4BuildConfiguration
+ 0
+ 0
+ 0
+
+ 3
+
+
+ 0
+ Deploy
+ Deploy
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+
+ false
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+ true
+ true
+ true
+
+ 2
+
+ ProjectExplorer.CustomExecutableRunConfiguration
+
+ false
+ true
+ false
+ true
+
+ 1
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 2
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 22
+
+
+ Version
+ 22
+
+
diff --git a/database.cpp b/database.cpp
new file mode 100644
index 0000000..48ebb76
--- /dev/null
+++ b/database.cpp
@@ -0,0 +1,169 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include "database.h"
+
+DataBase *DataBase::getInstance()
+{
+ static DataBase sqldb;
+ return &sqldb;
+}
+
+DataBase::DataBase()
+{
+ //先判断连接是否存在
+ if(QSqlDatabase::contains("testConnection"))
+ {
+ db_ = QSqlDatabase::addDatabase("testConnection");
+ }
+ else
+ {
+ //1.加载数据库驱动
+ db_ = QSqlDatabase::addDatabase("QSQLITE", "testConnection");
+ qDebug () << db_.connectionName();//打印连接名称
+
+ //2.设置数据库名
+ db_.setDatabaseName("usr.db");
+ qDebug () << db_.databaseName();
+ }
+
+ //3.打开数据库
+ if(db_.open())
+ {
+ qDebug() << "open success";
+ }
+ else
+ {
+ qDebug() << "open:" << db_.lastError().text();
+ return;
+ }
+
+ QString sql = "create table if not exists table_usr(name varchar(30) primary key, pwd varchar(20));";
+ QSqlQuery query(db_);
+ if (query.exec(sql))
+ {
+ qDebug() << "create success.";
+ }
+ db_.close();
+}
+
+
+//插入一个用户信息
+bool DataBase::insertUsr(QString name, QString pwd)
+{
+ QString sql = QString("insert into table_usr values('%1', '%2')")
+ .arg(name)
+ .arg(pwd);
+
+
+ // 1.打开数据
+ if (!db_.open())
+ {
+ qDebug() << "open:" << db_.lastError().text();
+ return false;
+ }
+
+ // 2.执行sql
+ QSqlQuery query(db_);
+ if (!query.exec(sql))
+ {
+ qDebug() << "insert:" << query.lastError().text();
+ return false;
+ }
+
+ //关闭数据库
+ db_.close();
+ return true;
+
+}
+
+
+//根据name查找用户
+bool DataBase::findUsr(QString name)
+{
+ QString sql = QString(" from table_usr where name = :name;");
+ //打开数据库
+ if(!db_.open())
+ {
+ qDebug() << "open fail" << db_.lastError().text();
+ exit(-1);
+ }
+
+ //执行插入操作
+ QSqlQuery query(db_);
+ query.prepare(sql);
+ query.bindValue(":name",QVariant(name));
+ query.exec();
+
+ //查询成功
+ if(query.next())
+ {
+ if(name == query.value(0).toString()) //用户存在
+ {
+ return true;
+ }
+ }
+
+ db_.close();
+ return false;
+}
+
+bool DataBase::Delete(QString name)
+{
+ QString sql = QString("select name from table_usr where name = :name;");
+ //打开数据库
+ if(!db_.open())
+ {
+ qDebug() << "open fail" << db_.lastError().text();
+ exit(-1);
+ }
+
+ //执行删除操作
+ QSqlQuery query(db_);
+
+ if (!query.exec(sql))
+ {
+ qDebug() << "delete" << query.lastError().text();
+ return false;
+ }
+
+ //关闭数据库
+ db_.close();
+ return true;
+}
+
+//匹配name和pwd
+bool DataBase::match(QString name, QString pwd)
+{
+ QString sql = QString("select name, pwd from table_usr where name = :name;");
+ //打开数据库
+ if(!db_.open())
+ {
+ qDebug() << "open fail" << db_.lastError().text();
+ exit(-1);
+ }
+
+ //执行插入操作
+ QSqlQuery query(db_);
+ query.prepare(sql);
+ query.bindValue(":name",QVariant(name));
+ query.exec();
+
+ //匹配密码
+ if(query.next())
+ {
+ if(!(pwd == query.value(1).toString()))
+ {
+ return false;
+ }
+ }
+
+ //关闭数据库
+ db_.close();
+
+ return true;
+}
+
diff --git a/database.h b/database.h
new file mode 100644
index 0000000..9629b4e
--- /dev/null
+++ b/database.h
@@ -0,0 +1,32 @@
+#ifndef DATABASE_H
+#define DATABASE_H
+#include
+#include
+#include
+#include
+#include
+
+class DataBase
+{
+public:
+ static DataBase *getInstance(); //静态的获取数据库对象的函数
+
+ //插入一个用户信息
+ bool insertUsr(QString name,QString pwd);
+
+ //根据name查找用户
+ bool findUsr(QString name);
+
+ //匹配name和pwd
+ bool match(QString name, QString pwd);
+
+ //删除用户信息
+ bool Delete(QString name);
+
+ DataBase();
+
+ QSqlDatabase db_;
+};
+
+#endif // DATABASE_H
+
diff --git a/datamanager.cpp b/datamanager.cpp
new file mode 100644
index 0000000..c81d9f8
--- /dev/null
+++ b/datamanager.cpp
@@ -0,0 +1,23 @@
+#include "datamanager.h"
+
+DataManager::DataManager(QObject *parent)
+ : QObject{parent}
+{
+ database = DataBase::getInstance();
+ protocol = Protocol::getInstance();
+ server = TCPServer::getInstance();
+ server->configAndrun();
+ server->setCallBack(disconnect_from_cln);
+ server->setCallBack(recv_from_cln);
+
+}
+
+void DataManager::disconnect_from_cln(QTcpSocket *sock)
+{
+
+}
+
+void DataManager::recv_from_cln(QByteArray &data, QTcpSocket *sock)
+{
+
+}
diff --git a/datamanager.h b/datamanager.h
new file mode 100644
index 0000000..6ad3a41
--- /dev/null
+++ b/datamanager.h
@@ -0,0 +1,28 @@
+#ifndef DATAMANAGER_H
+#define DATAMANAGER_H
+
+#include
+
+#include "database.h"
+#include "tcpserver.h"
+#include "protocol.h"
+
+class DataManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataManager(QObject *parent = nullptr);
+ static void disconnect_from_cln(QTcpSocket* sock);
+ static void recv_from_cln(QByteArray &data, QTcpSocket* sock);
+
+signals:
+
+private:
+ DataBase *database;
+ Protocol *protocol;
+ TCPServer *server;
+ QList online_socket_list;
+ QList online_name_list;
+};
+
+#endif // DATAMANAGER_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..05eaa16
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,10 @@
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ DataManager datamanager;
+ return a.exec();
+}
diff --git a/protocol.cpp b/protocol.cpp
new file mode 100644
index 0000000..98db9b4
--- /dev/null
+++ b/protocol.cpp
@@ -0,0 +1,152 @@
+#include "protocol.h"
+#include
+#include
+
+Protocol Protocol::protocol_instance;
+Protocol::Protocol(QObject *parent)
+ : QObject{parent}
+{
+
+}
+
+Protocol::~Protocol()
+{
+
+}
+
+Protocol* Protocol::getInstance()
+{
+ return &protocol_instance;
+}
+
+QByteArray Protocol::data_builder(QList &args)
+{
+ QJsonObject data;
+ switch(args[0].get_data_types())
+ {
+ case MESSAGE:
+ {
+ if (args.length()==2)
+ {
+ data.insert("type","message");
+ data.insert("data",args[1].get_string());
+ }
+ else if (args.length()==3)
+ {
+ data.insert("type","message");
+ data.insert("to_user",args[1].get_string());
+ data.insert("data",args[2].get_string());
+ }
+ break;
+ }
+ case FILE:
+ {
+ data.insert("type","file");
+ data.insert("name",args[1].get_string());
+ data.insert("data",args[2].get_string());
+ break;
+ }
+ case REQUEST:
+ {
+ data.insert("type","request");
+ data.insert("action",args[1].get_string());
+ QList content = args[2].get_list();
+ QJsonObject json_content;
+ for (int i=0; i users = args[2].get_list();
+ QJsonArray json_users;
+ for (auto &user:users)
+ json_users.append(user);
+ data.insert("users",json_users);
+ break;
+ }
+ case RESPONSE:
+ {
+ data.insert("type","response");
+ data.insert("action",args[1].get_string());
+ QList content = args[2].get_list();
+ QJsonObject json_content;
+ for (int i=0; i Protocol::data_parser(QByteArray data)
+{
+ QJsonDocument json_data = QJsonDocument::fromJson(data);
+ if (json_data["type"] == "message")
+ return qMakePair(MESSAGE,json_data.object());
+ else if (json_data["type"] == "file")
+ return qMakePair(FILE,json_data.object());
+ else if (json_data["type"] == "request")
+ return qMakePair(REQUEST,json_data.object());
+ else if (json_data["type"] == "online_users")
+ return qMakePair(ONLINEUSERS,json_data.object());
+ else if (json_data["type"] == "response")
+ return qMakePair(RESPONSE,json_data.object());
+ else
+ return qMakePair(RESPONSE,json_data.object());
+}
+
+QByteArray Protocol::XOR_En_Decrypt(QString src)
+{
+ QByteArray result;
+ for(auto &i:src)
+ result.append(i.toLatin1() ^ cipher_word);
+ return result;
+}
+
+QByteArray Protocol::Upper_Lower_En_Decrypt(QString src)
+{
+ QByteArray result;
+ for(auto &i:src)
+ {
+ if(i.isUpper())
+ {
+ QChar word = i.toLower();
+ result.append(word.toLatin1());
+ }
+ else if (i.isLower())
+ {
+ QChar word = i.toUpper();
+ result.append(word.toLatin1());
+ }
+ else
+ result.append(i.toLatin1());
+ }
+ return result;
+}
+
+QByteArray Protocol::data_encrypt(QByteArray src)
+{
+ QByteArray en_base64 = src.toBase64();
+ QByteArray result = Upper_Lower_En_Decrypt(en_base64);
+ return XOR_En_Decrypt(result);
+}
+
+QByteArray Protocol::data_decrypt(QByteArray src)
+{
+ QByteArray result = XOR_En_Decrypt(src);
+ result = Upper_Lower_En_Decrypt(result);
+ return QByteArray::fromBase64(result);
+}
+
+void Protocol::set_data_cipher_word(char word)
+{
+ cipher_word = word;
+}
diff --git a/protocol.h b/protocol.h
new file mode 100644
index 0000000..b6ccef1
--- /dev/null
+++ b/protocol.h
@@ -0,0 +1,60 @@
+#ifndef PROTOCOL_H
+#define PROTOCOL_H
+
+#include
+#include
+
+class Protocol : public QObject
+{
+ Q_OBJECT
+public:
+ static Protocol* getInstance();
+ template
+ QByteArray data_maker(Type type, Args ...args)
+ {
+ QList args_list;
+ args_list.append(any_types(type));
+ (void)std::initializer_list {(args_list.append(any_types(args)),0)...};
+ return data_builder(args_list);
+ };
+ enum data_types {MESSAGE,FILE,REQUEST,ONLINEUSERS,RESPONSE};
+ QPair data_parser(QByteArray data);
+ QByteArray data_encrypt(QByteArray src);
+ void set_data_cipher_word(char word);
+ QByteArray data_decrypt(QByteArray src);
+private:
+ char cipher_word = 'G';
+ struct any_types {
+ enum type {String, Bool, Int, Data_types, List};
+ any_types(int e) { m_data.INT = e; m_type = Int;}
+ any_types(QString e) { m_data.STRING = e; m_type = String;}
+ any_types(QList e) { m_data.LIST = e; m_type = List;}
+ any_types(bool e) { m_data.BOOL = e; m_type = Bool;}
+ any_types(data_types e) { m_data.DATA_TYPES = e; m_type = Data_types;}
+ type get_type() const { return m_type; }
+ int get_int() const { return m_data.INT; }
+ bool get_bool() const { return m_data.BOOL; }
+ data_types get_data_types() const { return m_data.DATA_TYPES; }
+ QString get_string() const { return m_data.STRING; }
+ QList get_list() const { return m_data.LIST; }
+ private:
+ type m_type;
+ struct {
+ int INT;
+ bool BOOL;
+ QString STRING;
+ QList LIST;
+ data_types DATA_TYPES;
+ } m_data;
+ };
+ static Protocol protocol_instance;
+ explicit Protocol(QObject *parent = nullptr);
+ ~Protocol();
+ QByteArray data_builder(QList &args);
+ QByteArray XOR_En_Decrypt(QString src);
+ QByteArray Upper_Lower_En_Decrypt(QString src);
+signals:
+
+};
+#endif // PROTOCOL_H
+
diff --git a/tcpserver.cpp b/tcpserver.cpp
new file mode 100644
index 0000000..eeca19a
--- /dev/null
+++ b/tcpserver.cpp
@@ -0,0 +1,124 @@
+#include "tcpserver.h"
+
+using namespace std;
+
+TCPServer TCPServer::tcpserver_instance;
+
+TCPServer::TCPServer(QObject *parent)
+ : QObject{parent}
+{
+
+}
+
+TCPServer::~TCPServer()
+{
+
+}
+
+TCPServer* TCPServer::getInstance()
+{
+ return &tcpserver_instance;
+}
+
+void TCPServer::configAndrun()
+{
+ tcp_server.listen(QHostAddress(listen_addr), listen_port);
+ connect(&tcp_server, &QTcpServer::newConnection, this, &TCPServer::acceptTCPConnection);
+ QByteArray addr = listen_addr.toLocal8Bit();
+ qDebug() << "successfully start server";
+ printf("TCP Server Started at %.*s:%d.\n", addr.length(), addr.data(),listen_port);
+}
+
+void TCPServer::setServer(QString IP, qint16 port)
+{
+ listen_addr = IP;
+ listen_port = port;
+}
+
+void TCPServer::stopRun()
+{
+ tcp_server.close();
+ QByteArray addr = listen_addr.toLocal8Bit();
+ printf("TCP Server Closed at %.*s:%d.\n",addr.length(), addr.data(),listen_port);
+}
+
+void TCPServer::acceptTCPConnection()
+{
+ QTcpSocket* clientConnection = tcp_server.nextPendingConnection();
+ if(clientConnection!=nullptr)
+ {
+ qDebug() << "new conncection";
+ clientConnection->setParent(this);
+ tcp_socket_list.append(clientConnection);
+ connect(clientConnection, &QTcpSocket::readyRead, this, &TCPServer::TCPReadPeer);
+ connect(clientConnection,&QTcpSocket::disconnected,this,&TCPServer::discTCPConnection);
+ QString ip = clientConnection->peerAddress().toString();
+ string ip_t = ip.toStdString();
+ printf("TCP: %.*s:%d connected.\n",ip_t.length(), ip_t.data(), clientConnection->peerPort());
+ }
+}
+
+void TCPServer::discTCPConnection()
+{
+ for (int i=0;i(sender()))//可以直接用sender()解决,此处为稳健起见还是采取遍历
+ {
+ QString ip = tcp_socket_list[i]->peerAddress().toString();
+ string ip_t = ip.toStdString();
+ printf("TCP: %.*s:%d Disconnected.\n",ip_t.length(), ip_t.data(), tcp_socket_list[i]->peerPort());
+ if (disccallback != nullptr)
+ disccallback(tcp_socket_list[i]);
+ tcp_socket_list.removeAt(i);
+ dynamic_cast(sender())->deleteLater();
+ qDebug() << "disconnect";
+ break;
+ }
+ }
+}
+
+void TCPServer::TCPReadPeer()
+{
+ sock =(QTcpSocket *)sender();
+ QByteArray recv;
+ while(sock->bytesAvailable())//循环接收
+ {
+ recv += sock->readAll();
+ if (!sock->waitForReadyRead(20))//超时停止接收
+ {
+ /*QString error = sock->errorString();
+ string error_t = error.toStdString();
+ log_w("error:%d: %.*s", sock->error(),error_t.length(), error_t.data());*/
+ break;
+ }
+ }
+ QString ip = sock->peerAddress().toString();
+ string ip_t = ip.toStdString();
+ printf("TCPC: Recvd from %.*s:%d\n", ip_t.length(), ip_t.data(), sock->peerPort());
+ printf("TCP Message:%.*s\n",recv.size(),(char *)recv.data());
+ if (recvcallback != nullptr)
+ recvcallback(recv,sock);
+}
+
+void TCPServer::setCallBack(void (*callback)(QByteArray &data, QTcpSocket* socket))
+{
+ recvcallback = callback;
+}
+
+void TCPServer::setCallBack(void (*callback)(QTcpSocket* socket))
+{
+ disccallback = callback;
+}
+
+void TCPServer::sendToclient(QString ip, quint16 port, QByteArray data)
+{
+ QHostAddress addr(ip);
+ for (int i=0;ipeerAddress()&&tcp_socket_list[i]->peerPort()==port)
+ {
+ tcp_socket_list[i]->write(data);
+ break;
+ }
+ }
+}
diff --git a/tcpserver.h b/tcpserver.h
new file mode 100644
index 0000000..6c2be3d
--- /dev/null
+++ b/tcpserver.h
@@ -0,0 +1,38 @@
+#ifndef TCPSERVER_H
+#define TCPSERVER_H
+
+#include
+#include
+#include
+#include
+
+class TCPServer : public QObject
+{
+ Q_OBJECT
+public:
+ static TCPServer* getInstance();
+ void configAndrun();
+ void setServer(QString IP, qint16 port);
+ void setCallBack(void (*callback)(QByteArray &data,QTcpSocket* socket));//Qt的信号-槽机制实际就是回调函数,
+ void setCallBack(void (*callback)(QTcpSocket* socket)); //此处为练手,不使用该机制
+ void sendToclient(QString ip, quint16 port, QByteArray data);
+ void stopRun();
+private:
+ explicit TCPServer(QObject *parent = nullptr);
+ ~TCPServer();
+ QString listen_addr = "0.0.0.0";
+ qint16 listen_port = 7890;
+ QTcpServer tcp_server;
+ QTcpSocket* sock;
+ QList tcp_socket_list;
+ void (*recvcallback) (QByteArray &data, QTcpSocket* socket)=nullptr;
+ void (*disccallback) (QTcpSocket* socket)=nullptr;
+ static TCPServer tcpserver_instance;
+private slots:
+ void acceptTCPConnection();
+ void TCPReadPeer();
+ void discTCPConnection();
+signals:
+};
+
+#endif // TCPSERVER_H