Initial commit
This commit is contained in:
parent
cbf3d39283
commit
0abbb46040
|
@ -0,0 +1,26 @@
|
||||||
|
QT -= gui
|
||||||
|
QT += network
|
||||||
|
CONFIG += c++11 console
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
|
||||||
|
# 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 += \
|
||||||
|
datamanager.cpp \
|
||||||
|
main.cpp \
|
||||||
|
protocol.cpp \
|
||||||
|
tcpclient.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 += \
|
||||||
|
datamanager.h \
|
||||||
|
protocol.h \
|
||||||
|
tcpclient.h \
|
||||||
|
tcpserver.h
|
|
@ -1,2 +1,2 @@
|
||||||
# data_manager
|
# data_manager
|
||||||
一个轻量级、可拓展的,基于Json的通信协议。
|
一个轻量级、可拓展的,基于Json的通信协议(开发中)。
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "datamanager.h"
|
||||||
|
|
||||||
|
DataManager::DataManager(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef DATAMANAGER_H
|
||||||
|
#define DATAMANAGER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class DataManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DataManager(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATAMANAGER_H
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include "protocol.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication a(argc, argv);
|
||||||
|
Protocol *p = Protocol::getInstance();
|
||||||
|
QList<QString> users{QString("123321123"),QString("123321123"),QString("123321123"),QString("123321123")};
|
||||||
|
qDebug()<<p->data_parser(p->data_maker(Protocol::ONLINEUSERS,4,users));
|
||||||
|
qDebug()<<p->data_encrypt(p->data_maker(Protocol::ONLINEUSERS,4,users));
|
||||||
|
qDebug()<<p->data_decrypt(p->data_encrypt(p->data_maker(Protocol::ONLINEUSERS,4,users)));
|
||||||
|
return a.exec();
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
#include "protocol.h"
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
Protocol Protocol::protocol_instance;
|
||||||
|
Protocol::Protocol(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol::~Protocol()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Protocol* Protocol::getInstance()
|
||||||
|
{
|
||||||
|
return &protocol_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Protocol::data_builder(QList<any_types> &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<QString> content = args[2].get_list();
|
||||||
|
QJsonObject json_content;
|
||||||
|
for (int i=0; i<content.length(); i+=2)
|
||||||
|
json_content.insert(content[i],content[i+1]);
|
||||||
|
data.insert("content",json_content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ONLINEUSERS:
|
||||||
|
{
|
||||||
|
data.insert("type","online_users");
|
||||||
|
data.insert("count",args[1].get_int());
|
||||||
|
QList<QString> 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<QString> content = args[2].get_list();
|
||||||
|
QJsonObject json_content;
|
||||||
|
for (int i=0; i<content.length(); i+=2)
|
||||||
|
json_content.insert(content[i],content[i+1]);
|
||||||
|
data.insert("content",json_content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QJsonDocument data_doc(data);
|
||||||
|
return data_doc.toJson(QJsonDocument::Compact)+'\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
QPair<Protocol::data_types,QJsonObject> 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;
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef PROTOCOL_H
|
||||||
|
#define PROTOCOL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
class Protocol : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static Protocol* getInstance();
|
||||||
|
template<typename Type, typename ...Args>
|
||||||
|
QByteArray data_maker(Type type, Args ...args)
|
||||||
|
{
|
||||||
|
QList<any_types> args_list;
|
||||||
|
args_list.append(any_types(type));
|
||||||
|
(void)std::initializer_list <int> {(args_list.append(any_types(args)),0)...};
|
||||||
|
return data_builder(args_list);
|
||||||
|
};
|
||||||
|
enum data_types {MESSAGE,FILE,REQUEST,ONLINEUSERS,RESPONSE};
|
||||||
|
QPair<data_types,QJsonObject> 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<QString> 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<QString> get_list() const { return m_data.LIST; }
|
||||||
|
private:
|
||||||
|
type m_type;
|
||||||
|
struct {
|
||||||
|
int INT;
|
||||||
|
bool BOOL;
|
||||||
|
QString STRING;
|
||||||
|
QList<QString> LIST;
|
||||||
|
data_types DATA_TYPES;
|
||||||
|
} m_data;
|
||||||
|
};
|
||||||
|
static Protocol protocol_instance;
|
||||||
|
explicit Protocol(QObject *parent = nullptr);
|
||||||
|
~Protocol();
|
||||||
|
QByteArray data_builder(QList<any_types> &args);
|
||||||
|
QByteArray XOR_En_Decrypt(QString src);
|
||||||
|
QByteArray Upper_Lower_En_Decrypt(QString src);
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif // PROTOCOL_H
|
|
@ -0,0 +1,96 @@
|
||||||
|
#include "tcpclient.h"
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
TCPClient TCPClient::tcpclient_instance;
|
||||||
|
QTcpSocket TCPClient::socket;
|
||||||
|
|
||||||
|
TCPClient::TCPClient(QObject *parent)
|
||||||
|
: QObject{parent}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPClient::~TCPClient()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TCPClient* TCPClient::getInstance()
|
||||||
|
{
|
||||||
|
return &tcpclient_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::configAndrun()
|
||||||
|
{
|
||||||
|
socket.setSocketOption(QAbstractSocket::KeepAliveOption,1);
|
||||||
|
socket.connectToHost(server_ip, server_port);
|
||||||
|
connect(&socket,&QTcpSocket::connected,this,&TCPClient::connected);
|
||||||
|
connect(&socket,&QTcpSocket::disconnected,this,&TCPClient::disconnected);
|
||||||
|
connect(&socket,&QTcpSocket::readyRead,this,&TCPClient::readSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::sendToserver(QByteArray &data)
|
||||||
|
{
|
||||||
|
if (socket.isOpen())
|
||||||
|
{
|
||||||
|
socket.write(data);
|
||||||
|
socket.waitForBytesWritten(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::setServer(QString IP, qint16 port)
|
||||||
|
{
|
||||||
|
server_ip = IP;
|
||||||
|
server_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::connected()
|
||||||
|
{
|
||||||
|
emit TCPClientConnected();
|
||||||
|
QString addr_t = socket.peerAddress().toString();
|
||||||
|
QByteArray addr = addr_t.toLocal8Bit();
|
||||||
|
printf("Connected to server at %.*s:%d.\n",addr.size(),addr.data(),socket.peerPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::disconnected()
|
||||||
|
{
|
||||||
|
emit TCPClientDisconnected();
|
||||||
|
printf("Disconnected from server.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::readSocket()
|
||||||
|
{
|
||||||
|
QByteArray recv;
|
||||||
|
while(socket.bytesAvailable())//循环接收
|
||||||
|
{
|
||||||
|
recv += socket.readAll();
|
||||||
|
if (!socket.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 = socket.peerAddress().toString();
|
||||||
|
string ip_t = ip.toStdString();
|
||||||
|
printf("TCPC: Recvd from %.*s:%d\n", ip_t.length(), ip_t.data(), socket.peerPort());
|
||||||
|
printf("TCPC Message:%.*s\n",recv.size(),(char *)recv.data());
|
||||||
|
if (_callback != nullptr)
|
||||||
|
_callback(ip, socket.peerPort(),recv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::setCallBack(void (*callback)(QString &mac, quint16 port, QByteArray &data))
|
||||||
|
{
|
||||||
|
_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPClient::_sleep(int msec)
|
||||||
|
{
|
||||||
|
QTime dieTime = QTime::currentTime().addMSecs(msec);
|
||||||
|
while( QTime::currentTime() < dieTime )
|
||||||
|
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef TCPCLIENT_H
|
||||||
|
#define TCPCLIENT_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class TCPClient : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static TCPClient* getInstance();
|
||||||
|
static void sendToserver(QByteArray &data);
|
||||||
|
void configAndrun();
|
||||||
|
void setCallBack(void (*callback)(QString &ip, quint16 port, QByteArray &data));
|
||||||
|
void setServer(QString IP, qint16 port);
|
||||||
|
private slots:
|
||||||
|
void connected();
|
||||||
|
void readSocket();
|
||||||
|
void disconnected();
|
||||||
|
private:
|
||||||
|
explicit TCPClient(QObject *parent = nullptr);
|
||||||
|
~TCPClient();
|
||||||
|
static void _sleep(int msec);
|
||||||
|
static QTcpSocket socket;
|
||||||
|
static TCPClient tcpclient_instance;
|
||||||
|
QString server_ip = "127.0.0.1";
|
||||||
|
qint16 server_port = 7890;
|
||||||
|
bool has_found = false;
|
||||||
|
void (*_callback) (QString &ip, quint16 port, QByteArray &data)=nullptr;
|
||||||
|
signals:
|
||||||
|
void TCPClientConnected();
|
||||||
|
void TCPClientDisconnected();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TCPCLIENT_H
|
|
@ -0,0 +1,121 @@
|
||||||
|
#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();
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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<tcp_socket_list.length();i++)
|
||||||
|
{
|
||||||
|
if (tcp_socket_list[i] == dynamic_cast<QTcpSocket*>(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(ip, tcp_socket_list[i]->peerPort());
|
||||||
|
tcp_socket_list.removeAt(i);
|
||||||
|
dynamic_cast<QTcpSocket*>(sender())->deleteLater();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::TCPReadPeer()
|
||||||
|
{
|
||||||
|
QTcpSocket* 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(ip, sock->peerPort(),recv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::setCallBack(void (*callback)(QString &ip, quint16 port, QByteArray &data))
|
||||||
|
{
|
||||||
|
recvcallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::setCallBack(void (*callback)(QString &ip, quint16 port))
|
||||||
|
{
|
||||||
|
disccallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPServer::sendToclient(QString ip, quint16 port, QByteArray data)
|
||||||
|
{
|
||||||
|
QHostAddress addr(ip);
|
||||||
|
for (int i=0;i<tcp_socket_list.length();i++)
|
||||||
|
{
|
||||||
|
if (addr == tcp_socket_list[i]->peerAddress()&&tcp_socket_list[i]->peerPort()==port)
|
||||||
|
{
|
||||||
|
tcp_socket_list[i]->write(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef TCPSERVER_H
|
||||||
|
#define TCPSERVER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
class TCPServer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static TCPServer* getInstance();
|
||||||
|
void configAndrun();
|
||||||
|
void setServer(QString IP, qint16 port);
|
||||||
|
void setCallBack(void (*callback)(QString &ip, quint16 port, QByteArray &data));//Qt的信号-槽机制实际就是回调函数,
|
||||||
|
void setCallBack(void (*callback)(QString &ip, quint16 port)); //此处为练手,不使用该机制
|
||||||
|
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;
|
||||||
|
QList <QTcpSocket*> tcp_socket_list;
|
||||||
|
void (*recvcallback) (QString &ip, quint16 port, QByteArray &data)=nullptr;
|
||||||
|
void (*disccallback) (QString &ip, quint16 port)=nullptr;
|
||||||
|
static TCPServer tcpserver_instance;
|
||||||
|
private slots:
|
||||||
|
void acceptTCPConnection();
|
||||||
|
void TCPReadPeer();
|
||||||
|
void discTCPConnection();
|
||||||
|
signals:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TCPSERVER_H
|
Loading…
Reference in New Issue