commit 2992ccd00dc49143c5c2a81bd8ff78fb6ca98349
Author: Msy-msu <2200456405@qq.com>
Date: Thu Jan 5 19:50:19 2023 +0800
first commit
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