彻底改版2.0

This commit is contained in:
feiyangqingyun
2021-11-17 16:41:30 +08:00
parent a7f4347959
commit ebfd531a91
2622 changed files with 8915 additions and 7263 deletions

21
tool/nettool/api/api.pri Normal file
View File

@@ -0,0 +1,21 @@
HEADERS += $$PWD/appconfig.h \
$$PWD/appdata.h \
$$PWD/quihelper.h \
$$PWD/quihelperdata.h
HEADERS += $$PWD/tcpclient.h
HEADERS += $$PWD/tcpserver.h
SOURCES += $$PWD/appconfig.cpp \
$$PWD/appdata.cpp \
$$PWD/quihelper.cpp \
$$PWD/quihelperdata.cpp
SOURCES += $$PWD/tcpclient.cpp
SOURCES += $$PWD/tcpserver.cpp
contains(DEFINES, websocket) {
HEADERS += $$PWD/webclient.h
HEADERS += $$PWD/webserver.h
SOURCES += $$PWD/webclient.cpp
SOURCES += $$PWD/webserver.cpp
}

View File

@@ -0,0 +1,230 @@
#include "appconfig.h"
#include "quihelper.h"
QString AppConfig::ConfigFile = "config.ini";
int AppConfig::CurrentIndex = 0;
bool AppConfig::HexSendTcpClient = false;
bool AppConfig::HexReceiveTcpClient = false;
bool AppConfig::AsciiTcpClient = false;
bool AppConfig::DebugTcpClient = false;
bool AppConfig::AutoSendTcpClient = false;
int AppConfig::IntervalTcpClient = 1000;
QString AppConfig::TcpBindIP = "127.0.0.1";
int AppConfig::TcpBindPort = 6001;
QString AppConfig::TcpServerIP = "127.0.0.1";
int AppConfig::TcpServerPort = 6000;
bool AppConfig::HexSendTcpServer = false;
bool AppConfig::HexReceiveTcpServer = false;
bool AppConfig::AsciiTcpServer = false;
bool AppConfig::DebugTcpServer = false;
bool AppConfig::AutoSendTcpServer = false;
int AppConfig::IntervalTcpServer = 1000;
QString AppConfig::TcpListenIP = "127.0.0.1";
int AppConfig::TcpListenPort = 6000;
bool AppConfig::SelectAllTcpServer = true;
bool AppConfig::HexSendUdpClient = false;
bool AppConfig::HexReceiveUdpClient = false;
bool AppConfig::AsciiUdpClient = false;
bool AppConfig::DebugUdpClient = false;
bool AppConfig::AutoSendUdpClient = false;
int AppConfig::IntervalUdpClient = 1000;
QString AppConfig::UdpBindIP = "127.0.0.1";
int AppConfig::UdpBindPort = 6001;
QString AppConfig::UdpServerIP = "127.0.0.1";
int AppConfig::UdpServerPort = 6000;
bool AppConfig::HexSendUdpServer = false;
bool AppConfig::HexReceiveUdpServer = false;
bool AppConfig::AsciiUdpServer = false;
bool AppConfig::DebugUdpServer = false;
bool AppConfig::AutoSendUdpServer = false;
int AppConfig::IntervalUdpServer = 1000;
QString AppConfig::UdpListenIP = "127.0.0.1";
int AppConfig::UdpListenPort = 6000;
bool AppConfig::SelectAllUdpServer = false;
bool AppConfig::HexSendWebClient = false;
bool AppConfig::HexReceiveWebClient = false;
bool AppConfig::AsciiWebClient = true;
bool AppConfig::DebugWebClient = false;
bool AppConfig::AutoSendWebClient = false;
int AppConfig::IntervalWebClient = 1000;
QString AppConfig::WebServerIP = "ws://127.0.0.1";
int AppConfig::WebServerPort = 6000;
bool AppConfig::HexSendWebServer = false;
bool AppConfig::HexReceiveWebServer = false;
bool AppConfig::AsciiWebServer = true;
bool AppConfig::DebugWebServer = false;
bool AppConfig::AutoSendWebServer = false;
int AppConfig::IntervalWebServer = 1000;
QString AppConfig::WebListenIP = "127.0.0.1";
int AppConfig::WebListenPort = 6000;
bool AppConfig::SelectAllWebServer = true;
void AppConfig::readConfig()
{
QSettings set(AppConfig::ConfigFile, QSettings::IniFormat);
set.beginGroup("AppConfig");
AppConfig::CurrentIndex = set.value("CurrentIndex").toInt();
set.endGroup();
set.beginGroup("TcpClientConfig");
AppConfig::HexSendTcpClient = set.value("HexSendTcpClient", AppConfig::HexSendTcpClient).toBool();
AppConfig::HexReceiveTcpClient = set.value("HexReceiveTcpClient", AppConfig::HexReceiveTcpClient).toBool();
AppConfig::AsciiTcpClient = set.value("AsciiTcpClient", AppConfig::AsciiTcpClient).toBool();
AppConfig::DebugTcpClient = set.value("DebugTcpClient", AppConfig::DebugTcpClient).toBool();
AppConfig::AutoSendTcpClient = set.value("AutoSendTcpClient", AppConfig::AutoSendTcpClient).toBool();
AppConfig::IntervalTcpClient = set.value("IntervalTcpClient", AppConfig::IntervalTcpClient).toInt();
AppConfig::TcpBindIP = set.value("TcpBindIP", AppConfig::TcpBindIP).toString();
AppConfig::TcpBindPort = set.value("TcpBindPort", AppConfig::TcpBindPort).toInt();
AppConfig::TcpServerIP = set.value("TcpServerIP", AppConfig::TcpServerIP).toString();
AppConfig::TcpServerPort = set.value("TcpServerPort", AppConfig::TcpServerPort).toInt();
set.endGroup();
set.beginGroup("TcpServerConfig");
AppConfig::HexSendTcpServer = set.value("HexSendTcpServer", AppConfig::HexSendTcpServer).toBool();
AppConfig::HexReceiveTcpServer = set.value("HexReceiveTcpServer", AppConfig::HexReceiveTcpServer).toBool();
AppConfig::AsciiTcpServer = set.value("AsciiTcpServer", AppConfig::AsciiTcpServer).toBool();
AppConfig::DebugTcpServer = set.value("DebugTcpServer", AppConfig::DebugTcpServer).toBool();
AppConfig::AutoSendTcpServer = set.value("AutoSendTcpServer", AppConfig::AutoSendTcpServer).toBool();
AppConfig::IntervalTcpServer = set.value("IntervalTcpServer", AppConfig::IntervalTcpServer).toInt();
AppConfig::TcpListenIP = set.value("TcpListenIP", AppConfig::TcpListenIP).toString();
AppConfig::TcpListenPort = set.value("TcpListenPort", AppConfig::TcpListenPort).toInt();
AppConfig::SelectAllTcpServer = set.value("SelectAllTcpServer", AppConfig::SelectAllTcpServer).toBool();
set.endGroup();
set.beginGroup("UdpClientConfig");
AppConfig::HexSendUdpClient = set.value("HexSendUdpClient", AppConfig::HexSendUdpClient).toBool();
AppConfig::HexReceiveUdpClient = set.value("HexReceiveUdpClient", AppConfig::HexReceiveUdpClient).toBool();
AppConfig::AsciiUdpClient = set.value("AsciiUdpClient", AppConfig::AsciiUdpClient).toBool();
AppConfig::DebugUdpClient = set.value("DebugUdpClient", AppConfig::DebugUdpClient).toBool();
AppConfig::AutoSendUdpClient = set.value("AutoSendUdpClient", AppConfig::AutoSendUdpClient).toBool();
AppConfig::IntervalUdpClient = set.value("IntervalUdpClient", AppConfig::IntervalUdpClient).toInt();
AppConfig::UdpBindIP = set.value("UdpBindIP", AppConfig::UdpBindIP).toString();
AppConfig::UdpBindPort = set.value("UdpBindPort", AppConfig::UdpBindPort).toInt();
AppConfig::UdpServerIP = set.value("UdpServerIP", AppConfig::UdpServerIP).toString();
AppConfig::UdpServerPort = set.value("UdpServerPort", AppConfig::UdpServerPort).toInt();
set.endGroup();
set.beginGroup("UdpServerConfig");
AppConfig::HexSendUdpServer = set.value("HexSendUdpServer", AppConfig::HexSendUdpServer).toBool();
AppConfig::HexReceiveUdpServer = set.value("HexReceiveUdpServer", AppConfig::HexReceiveUdpServer).toBool();
AppConfig::AsciiUdpServer = set.value("AsciiUdpServer", AppConfig::AsciiUdpServer).toBool();
AppConfig::DebugUdpServer = set.value("DebugUdpServer", AppConfig::DebugUdpServer).toBool();
AppConfig::AutoSendUdpServer = set.value("AutoSendUdpServer", AppConfig::AutoSendUdpServer).toBool();
AppConfig::IntervalUdpServer = set.value("IntervalUdpServer", AppConfig::IntervalUdpServer).toInt();
AppConfig::UdpListenIP = set.value("UdpListenIP", AppConfig::UdpListenIP).toString();
AppConfig::UdpListenPort = set.value("UdpListenPort", AppConfig::UdpListenPort).toInt();
AppConfig::SelectAllUdpServer = set.value("SelectAllUdpServer", AppConfig::SelectAllUdpServer).toBool();
set.endGroup();
set.beginGroup("WebClientConfig");
AppConfig::HexSendWebClient = set.value("HexSendWebClient", AppConfig::HexSendWebClient).toBool();
AppConfig::HexReceiveWebClient = set.value("HexReceiveWebClient", AppConfig::HexReceiveWebClient).toBool();
AppConfig::AsciiWebClient = set.value("AsciiWebClient", AppConfig::AsciiWebClient).toBool();
AppConfig::DebugWebClient = set.value("DebugWebClient", AppConfig::DebugWebClient).toBool();
AppConfig::AutoSendWebClient = set.value("AutoSendWebClient", AppConfig::AutoSendWebClient).toBool();
AppConfig::IntervalWebClient = set.value("IntervalWebClient", AppConfig::IntervalWebClient).toInt();
AppConfig::WebServerIP = set.value("WebServerIP", AppConfig::WebServerIP).toString();
AppConfig::WebServerPort = set.value("WebServerPort", AppConfig::WebServerPort).toInt();
set.endGroup();
set.beginGroup("WebServerConfig");
AppConfig::HexSendWebServer = set.value("HexSendWebServer", AppConfig::HexSendWebServer).toBool();
AppConfig::HexReceiveWebServer = set.value("HexReceiveWebServer", AppConfig::HexReceiveWebServer).toBool();
AppConfig::AsciiWebServer = set.value("AsciiWebServer", AppConfig::AsciiWebServer).toBool();
AppConfig::DebugWebServer = set.value("DebugWebServer", AppConfig::DebugWebServer).toBool();
AppConfig::AutoSendWebServer = set.value("AutoSendWebServer", AppConfig::AutoSendWebServer).toBool();
AppConfig::IntervalWebServer = set.value("IntervalWebServer", AppConfig::IntervalWebServer).toInt();
AppConfig::WebListenIP = set.value("WebListenIP", AppConfig::WebListenIP).toString();
AppConfig::WebListenPort = set.value("WebListenPort", AppConfig::WebListenPort).toInt();
AppConfig::SelectAllWebServer = set.value("SelectAllWebServer", AppConfig::SelectAllWebServer).toBool();
set.endGroup();
//配置文件不存在或者不全则重新生成
if (!QUIHelper::checkIniFile(AppConfig::ConfigFile)) {
writeConfig();
return;
}
}
void AppConfig::writeConfig()
{
QSettings set(AppConfig::ConfigFile, QSettings::IniFormat);
set.beginGroup("AppConfig");
set.setValue("CurrentIndex", AppConfig::CurrentIndex);
set.endGroup();
set.beginGroup("TcpClientConfig");
set.setValue("HexSendTcpClient", AppConfig::HexSendTcpClient);
set.setValue("HexReceiveTcpClient", AppConfig::HexReceiveTcpClient);
set.setValue("DebugTcpClient", AppConfig::DebugTcpClient);
set.setValue("AutoSendTcpClient", AppConfig::AutoSendTcpClient);
set.setValue("IntervalTcpClient", AppConfig::IntervalTcpClient);
set.setValue("TcpBindIP", AppConfig::TcpBindIP);
set.setValue("TcpBindPort", AppConfig::TcpBindPort);
set.setValue("TcpServerIP", AppConfig::TcpServerIP);
set.setValue("TcpServerPort", AppConfig::TcpServerPort);
set.endGroup();
set.beginGroup("TcpServerConfig");
set.setValue("HexSendTcpServer", AppConfig::HexSendTcpServer);
set.setValue("HexReceiveTcpServer", AppConfig::HexReceiveTcpServer);
set.setValue("DebugTcpServer", AppConfig::DebugTcpServer);
set.setValue("AutoSendTcpServer", AppConfig::AutoSendTcpServer);
set.setValue("IntervalTcpServer", AppConfig::IntervalTcpServer);
set.setValue("TcpListenIP", AppConfig::TcpListenIP);
set.setValue("TcpListenPort", AppConfig::TcpListenPort);
set.setValue("SelectAllTcpServer", AppConfig::SelectAllTcpServer);
set.endGroup();
set.beginGroup("UdpClientConfig");
set.setValue("HexSendUdpClient", AppConfig::HexSendUdpClient);
set.setValue("HexReceiveUdpClient", AppConfig::HexReceiveUdpClient);
set.setValue("DebugUdpClient", AppConfig::DebugUdpClient);
set.setValue("AutoSendUdpClient", AppConfig::AutoSendUdpClient);
set.setValue("IntervalUdpClient", AppConfig::IntervalUdpClient);
set.setValue("UdpBindIP", AppConfig::UdpBindIP);
set.setValue("UdpBindPort", AppConfig::UdpBindPort);
set.setValue("UdpServerIP", AppConfig::UdpServerIP);
set.setValue("UdpServerPort", AppConfig::UdpServerPort);
set.endGroup();
set.beginGroup("UdpServerConfig");
set.setValue("HexSendUdpServer", AppConfig::HexSendUdpServer);
set.setValue("HexReceiveUdpServer", AppConfig::HexReceiveUdpServer);
set.setValue("DebugUdpServer", AppConfig::DebugUdpServer);
set.setValue("AutoSendUdpServer", AppConfig::AutoSendUdpServer);
set.setValue("IntervalUdpServer", AppConfig::IntervalUdpServer);
set.setValue("UdpListenIP", AppConfig::UdpListenIP);
set.setValue("UdpListenPort", AppConfig::UdpListenPort);
set.setValue("SelectAllUdpServer", AppConfig::SelectAllUdpServer);
set.endGroup();
set.beginGroup("WebClientConfig");
set.setValue("HexSendWebClient", AppConfig::HexSendWebClient);
set.setValue("HexReceiveWebClient", AppConfig::HexReceiveWebClient);
set.setValue("DebugWebClient", AppConfig::DebugWebClient);
set.setValue("AutoSendWebClient", AppConfig::AutoSendWebClient);
set.setValue("IntervalWebClient", AppConfig::IntervalWebClient);
set.setValue("WebServerIP", AppConfig::WebServerIP);
set.setValue("WebServerPort", AppConfig::WebServerPort);
set.endGroup();
set.beginGroup("WebServerConfig");
set.setValue("HexSendWebServer", AppConfig::HexSendWebServer);
set.setValue("HexReceiveWebServer", AppConfig::HexReceiveWebServer);
set.setValue("DebugWebServer", AppConfig::DebugWebServer);
set.setValue("AutoSendWebServer", AppConfig::AutoSendWebServer);
set.setValue("IntervalWebServer", AppConfig::IntervalWebServer);
set.setValue("WebListenIP", AppConfig::WebListenIP);
set.setValue("WebListenPort", AppConfig::WebListenPort);
set.setValue("SelectAllWebServer", AppConfig::SelectAllWebServer);
set.endGroup();
}

View File

@@ -0,0 +1,84 @@
#ifndef APPCONFIG_H
#define APPCONFIG_H
#include "head.h"
class AppConfig
{
public:
static QString ConfigFile; //配置文件路径
static int CurrentIndex; //当前索引
//TCP客户端配置参数
static bool HexSendTcpClient; //16进制发送
static bool HexReceiveTcpClient; //16进制接收
static bool AsciiTcpClient; //ASCII模式
static bool DebugTcpClient; //启用数据调试
static bool AutoSendTcpClient; //自动发送数据
static int IntervalTcpClient; //发送数据间隔
static QString TcpBindIP; //绑定地址
static int TcpBindPort; //绑定端口
static QString TcpServerIP; //服务器地址
static int TcpServerPort; //服务器端口
//TCP服务器配置参数
static bool HexSendTcpServer; //16进制发送
static bool HexReceiveTcpServer; //16进制接收
static bool AsciiTcpServer; //ASCII模式
static bool DebugTcpServer; //启用数据调试
static bool AutoSendTcpServer; //自动发送数据
static int IntervalTcpServer; //发送数据间隔
static QString TcpListenIP; //监听地址
static int TcpListenPort; //监听端口
static bool SelectAllTcpServer; //选中所有
//UDP客户端配置参数
static bool HexSendUdpClient; //16进制发送
static bool HexReceiveUdpClient; //16进制接收
static bool AsciiUdpClient; //ASCII模式
static bool DebugUdpClient; //启用数据调试
static bool AutoSendUdpClient; //自动发送数据
static int IntervalUdpClient; //发送数据间隔
static QString UdpBindIP; //绑定地址
static int UdpBindPort; //绑定端口
static QString UdpServerIP; //服务器地址
static int UdpServerPort; //服务器端口
//UDP服务器配置参数
static bool HexSendUdpServer; //16进制发送
static bool HexReceiveUdpServer; //16进制接收
static bool AsciiUdpServer; //ASCII模式
static bool DebugUdpServer; //启用数据调试
static bool AutoSendUdpServer; //自动发送数据
static int IntervalUdpServer; //发送数据间隔
static QString UdpListenIP; //监听地址
static int UdpListenPort; //监听端口
static bool SelectAllUdpServer; //选中所有
//WEB客户端配置参数
static bool HexSendWebClient; //16进制发送
static bool HexReceiveWebClient; //16进制接收
static bool AsciiWebClient; //ASCII模式
static bool DebugWebClient; //启用数据调试
static bool AutoSendWebClient; //自动发送数据
static int IntervalWebClient; //发送数据间隔
static QString WebServerIP; //服务器地址
static int WebServerPort; //服务器端口
//WEB服务器配置参数
static bool HexSendWebServer; //16进制发送
static bool HexReceiveWebServer; //16进制接收
static bool AsciiWebServer; //ASCII模式
static bool DebugWebServer; //启用数据调试
static bool AutoSendWebServer; //自动发送数据
static int IntervalWebServer; //发送数据间隔
static QString WebListenIP; //监听地址
static int WebListenPort; //监听端口
static bool SelectAllWebServer; //选中所有
//读写配置参数
static void readConfig(); //读取配置参数
static void writeConfig(); //写入配置参数
};
#endif // APPCONFIG_H

View File

@@ -0,0 +1,122 @@
#include "appdata.h"
#include "quihelper.h"
QStringList AppData::Intervals = QStringList();
QStringList AppData::Datas = QStringList();
QStringList AppData::Keys = QStringList();
QStringList AppData::Values = QStringList();
QString AppData::SendFileName = "send.txt";
void AppData::readSendData()
{
//读取发送数据列表
AppData::Datas.clear();
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::SendFileName);
QFile file(fileName);
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
while (!file.atEnd()) {
QString line = file.readLine();
line = line.trimmed();
line = line.replace("\r", "");
line = line.replace("\n", "");
if (!line.isEmpty()) {
AppData::Datas.append(line);
}
}
file.close();
}
//没有的时候主动添加点免得太空
if (AppData::Datas.count() == 0) {
AppData::Datas << "16 FF 01 01 E0 E1" << "16 FF 01 01 E1 E2";
}
}
QString AppData::DeviceFileName = "device.txt";
void AppData::readDeviceData()
{
//读取转发数据列表
AppData::Keys.clear();
AppData::Values.clear();
QString fileName = QString("%1/%2").arg(QUIHelper::appPath()).arg(AppData::DeviceFileName);
QFile file(fileName);
if (file.size() > 0 && file.open(QFile::ReadOnly | QIODevice::Text)) {
while (!file.atEnd()) {
QString line = file.readLine();
line = line.trimmed();
line = line.replace("\r", "");
line = line.replace("\n", "");
if (!line.isEmpty()) {
QStringList list = line.split(";");
QString key = list.at(0);
QString value;
for (int i = 1; i < list.count(); i++) {
value += QString("%1;").arg(list.at(i));
}
//去掉末尾分号
value = value.mid(0, value.length() - 1);
AppData::Keys.append(key);
AppData::Values.append(value);
}
}
file.close();
}
}
void AppData::saveData(const QString &data)
{
if (data.length() <= 0) {
return;
}
QString fileName = QString("%1/%2.txt").arg(QUIHelper::appPath()).arg(STRDATETIME);
QFile file(fileName);
if (file.open(QFile::WriteOnly | QFile::Text)) {
file.write(data.toUtf8());
file.close();
}
}
void AppData::loadIP(QComboBox *cbox)
{
//获取本机所有IP
static QStringList ips;
if (ips.count() == 0) {
#ifdef emsdk
ips << "127.0.0.1";
#else
QList<QNetworkInterface> netInterfaces = QNetworkInterface::allInterfaces();
foreach (const QNetworkInterface &netInterface, netInterfaces) {
//移除虚拟机和抓包工具的虚拟网卡
QString humanReadableName = netInterface.humanReadableName().toLower();
if (humanReadableName.startsWith("vmware network adapter") || humanReadableName.startsWith("npcap loopback adapter")) {
continue;
}
//过滤当前网络接口
bool flag = (netInterface.flags() == (QNetworkInterface::IsUp | QNetworkInterface::IsRunning | QNetworkInterface::CanBroadcast | QNetworkInterface::CanMulticast));
if (flag) {
QList<QNetworkAddressEntry> addrs = netInterface.addressEntries();
foreach (QNetworkAddressEntry addr, addrs) {
//只取出IPV4的地址
if (addr.ip().protocol() == QAbstractSocket::IPv4Protocol) {
QString ip4 = addr.ip().toString();
if (ip4 != "127.0.0.1") {
ips << ip4;
}
}
}
}
}
#endif
}
cbox->clear();
cbox->addItems(ips);
if (!ips.contains("127.0.0.1")) {
cbox->addItem("127.0.0.1");
}
}

View File

@@ -0,0 +1,30 @@
#ifndef APPDATA_H
#define APPDATA_H
#include "head.h"
class AppData
{
public:
//全局变量
static QStringList Intervals;
static QStringList Datas;
static QStringList Keys;
static QStringList Values;
//读取发送数据列表
static QString SendFileName;
static void readSendData();
//读取转发数据列表
static QString DeviceFileName;
static void readDeviceData();
//保存数据到文件
static void saveData(const QString &data);
//添加网卡IP地址到下拉框
static void loadIP(QComboBox *cbox);
};
#endif // APPDATA_H

View File

@@ -0,0 +1,420 @@
#include "quihelper.h"
int QUIHelper::getScreenIndex()
{
//需要对多个屏幕进行处理
int screenIndex = 0;
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
int screenCount = qApp->screens().count();
#else
int screenCount = qApp->desktop()->screenCount();
#endif
if (screenCount > 1) {
//找到当前鼠标所在屏幕
QPoint pos = QCursor::pos();
for (int i = 0; i < screenCount; ++i) {
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
if (qApp->screens().at(i)->geometry().contains(pos)) {
#else
if (qApp->desktop()->screenGeometry(i).contains(pos)) {
#endif
screenIndex = i;
break;
}
}
}
return screenIndex;
}
QRect QUIHelper::getScreenRect(bool available)
{
QRect rect;
int screenIndex = QUIHelper::getScreenIndex();
if (available) {
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
rect = qApp->screens().at(screenIndex)->availableGeometry();
#else
rect = qApp->desktop()->availableGeometry(screenIndex);
#endif
} else {
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
rect = qApp->screens().at(screenIndex)->geometry();
#else
rect = qApp->desktop()->screenGeometry(screenIndex);
#endif
}
return rect;
}
int QUIHelper::deskWidth()
{
return getScreenRect().width();
}
int QUIHelper::deskHeight()
{
return getScreenRect().height();
}
QWidget *QUIHelper::centerBaseForm = 0;
void QUIHelper::setFormInCenter(QWidget *form)
{
int formWidth = form->width();
int formHeight = form->height();
//如果=0表示采用系统桌面屏幕为参照
QRect rect;
if (centerBaseForm == 0) {
rect = getScreenRect();
} else {
rect = centerBaseForm->geometry();
}
int deskWidth = rect.width();
int deskHeight = rect.height();
QPoint movePoint(deskWidth / 2 - formWidth / 2 + rect.x(), deskHeight / 2 - formHeight / 2 + rect.y());
form->move(movePoint);
}
QString QUIHelper::appName()
{
//没有必要每次都获取,只有当变量为空时才去获取一次
static QString name;
if (name.isEmpty()) {
name = qApp->applicationFilePath();
//下面的方法主要为了过滤安卓的路径 lib程序名_armeabi-v7a
QStringList list = name.split("/");
name = list.at(list.count() - 1).split(".").at(0);
}
return name;
}
QString QUIHelper::appPath()
{
#ifdef Q_OS_ANDROID
//return QString("/sdcard/Android/%1").arg(appName());
return QString("/storage/emulated/0/%1").arg(appName());
#else
return qApp->applicationDirPath();
#endif
}
QString QUIHelper::getUuid()
{
QString uuid = QUuid::createUuid().toString();
uuid.replace("{", "");
uuid.replace("}", "");
return uuid;
}
void QUIHelper::initRand()
{
//初始化随机数种子
QTime t = QTime::currentTime();
srand(t.msec() + t.second() * 1000);
}
void QUIHelper::newDir(const QString &dirName)
{
QString strDir = dirName;
//如果路径中包含斜杠字符则说明是绝对路径
//linux系统路径字符带有 / windows系统 路径字符带有 :/
if (!strDir.startsWith("/") && !strDir.contains(":/")) {
strDir = QString("%1/%2").arg(QUIHelper::appPath()).arg(strDir);
}
QDir dir(strDir);
if (!dir.exists()) {
dir.mkpath(strDir);
}
}
void QUIHelper::sleep(int msec)
{
if (msec <= 0) {
return;
}
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
QThread::msleep(msec);
#else
QTime endTime = QTime::currentTime().addMSecs(msec);
while (QTime::currentTime() < endTime) {
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
#endif
}
void QUIHelper::setStyle()
{
//打印下所有内置风格的名字
qDebug() << "Qt内置的样式" << QStyleFactory::keys();
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
qApp->setStyle(QStyleFactory::create("Fusion"));
#else
qApp->setStyle(QStyleFactory::create("Cleanlooks"));
#endif
//qApp->setPalette(QPalette("#FFFFFF"));
}
void QUIHelper::setFont(int fontSize)
{
QFont font;
font.setFamily("MicroSoft Yahei");
#ifdef Q_OS_ANDROID
font.setPixelSize(15);
#elif __arm__
font.setPixelSize(25);
#else
font.setPixelSize(fontSize);
#endif
#ifndef rk3399
qApp->setFont(font);
#endif
}
void QUIHelper::setCode(bool utf8)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
//如果想要控制台打印信息中文正常就注释掉这个设置
if (utf8) {
QTextCodec *codec = QTextCodec::codecForName("utf-8");
QTextCodec::setCodecForLocale(codec);
}
#else
#if _MSC_VER
QTextCodec *codec = QTextCodec::codecForName("gbk");
#else
QTextCodec *codec = QTextCodec::codecForName("utf-8");
#endif
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
#endif
}
void QUIHelper::setTranslator(const QString &qmFile)
{
//过滤下不存在的就不用设置了
if (!QFile(qmFile).exists()) {
return;
}
QTranslator *translator = new QTranslator(qApp);
translator->load(qmFile);
qApp->installTranslator(translator);
}
void QUIHelper::initAll()
{
//初始化随机数种子
QUIHelper::initRand();
//设置样式风格
QUIHelper::setStyle();
//设置字体
QUIHelper::setFont(13);
//设置编码
QUIHelper::setCode();
//设置翻译文件支持多个
QUIHelper::setTranslator(":/qm/widgets.qm");
QUIHelper::setTranslator(":/qm/qt_zh_CN.qm");
QUIHelper::setTranslator(":/qm/designer_zh_CN.qm");
}
void QUIHelper::setFramelessForm(QWidget *widgetMain, bool tool, bool top, bool menu)
{
widgetMain->setProperty("form", true);
widgetMain->setProperty("canMove", true);
//根据设定逐个追加属性
#ifdef __arm__
widgetMain->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
#else
widgetMain->setWindowFlags(Qt::FramelessWindowHint);
#endif
if (tool) {
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::Tool);
}
if (top) {
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowStaysOnTopHint);
}
if (menu) {
//如果是其他系统比如neokylin会产生系统边框
#ifdef Q_OS_WIN
widgetMain->setWindowFlags(widgetMain->windowFlags() | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint);
#endif
}
}
int QUIHelper::showMessageBox(const QString &info, int type, int closeSec, bool exec)
{
int result = 0;
if (type == 0) {
showMessageBoxInfo(info, closeSec, exec);
} else if (type == 1) {
showMessageBoxError(info, closeSec, exec);
} else if (type == 2) {
result = showMessageBoxQuestion(info);
}
return result;
}
void QUIHelper::showMessageBoxInfo(const QString &info, int closeSec, bool exec)
{
QMessageBox box(QMessageBox::Information, "提示", info);
box.setStandardButtons(QMessageBox::Yes);
box.setButtonText(QMessageBox::Yes, QString("确 定"));
box.exec();
//QMessageBox::information(0, "提示", info, QMessageBox::Yes);
}
void QUIHelper::showMessageBoxError(const QString &info, int closeSec, bool exec)
{
QMessageBox box(QMessageBox::Critical, "错误", info);
box.setStandardButtons(QMessageBox::Yes);
box.setButtonText(QMessageBox::Yes, QString("确 定"));
box.exec();
//QMessageBox::critical(0, "错误", info, QMessageBox::Yes);
}
int QUIHelper::showMessageBoxQuestion(const QString &info)
{
QMessageBox box(QMessageBox::Question, "询问", info);
box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
box.setButtonText(QMessageBox::Yes, QString("确 定"));
box.setButtonText(QMessageBox::No, QString("取 消"));
return box.exec();
//return QMessageBox::question(0, "询问", info, QMessageBox::Yes | QMessageBox::No);
}
QString QUIHelper::getXorEncryptDecrypt(const QString &value, char key)
{
//矫正范围外的数据
if (key < 0 || key >= 127) {
key = 127;
}
QString result = value;
int count = result.count();
for (int i = 0; i < count; i++) {
result[i] = QChar(result.at(i).toLatin1() ^ key);
}
return result;
}
uchar QUIHelper::getOrCode(const QByteArray &data)
{
int len = data.length();
uchar result = 0;
for (int i = 0; i < len; i++) {
result ^= data.at(i);
}
return result;
}
uchar QUIHelper::getCheckCode(const QByteArray &data)
{
int len = data.length();
uchar temp = 0;
for (uchar i = 0; i < len; i++) {
temp += data.at(i);
}
return temp % 256;
}
void QUIHelper::initTableView(QTableView *tableView, int rowHeight, bool headVisible, bool edit, bool stretchLast)
{
//取消自动换行
tableView->setWordWrap(false);
//超出文本不显示省略号
tableView->setTextElideMode(Qt::ElideNone);
//奇数偶数行颜色交替
tableView->setAlternatingRowColors(false);
//垂直表头是否可见
tableView->verticalHeader()->setVisible(headVisible);
//选中一行表头是否加粗
tableView->horizontalHeader()->setHighlightSections(false);
//最后一行拉伸填充
tableView->horizontalHeader()->setStretchLastSection(stretchLast);
//行标题最小宽度尺寸
tableView->horizontalHeader()->setMinimumSectionSize(0);
//行标题最小高度,等同于和默认行高一致
tableView->horizontalHeader()->setFixedHeight(rowHeight);
//默认行高
tableView->verticalHeader()->setDefaultSectionSize(rowHeight);
//选中时一行整体选中
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
//只允许选择单个
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
//表头不可单击
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
tableView->horizontalHeader()->setSectionsClickable(false);
#else
tableView->horizontalHeader()->setClickable(false);
#endif
//鼠标按下即进入编辑模式
if (edit) {
tableView->setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::DoubleClicked);
} else {
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
}
void QUIHelper::openFile(const QString &fileName, const QString &msg)
{
#ifdef __arm__
return;
#endif
if (fileName.isEmpty()) {
return;
}
if (QUIHelper::showMessageBoxQuestion(msg + "成功!确定现在就打开吗?") == QMessageBox::Yes) {
QString url = QString("file:///%1").arg(fileName);
QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
}
}
bool QUIHelper::checkIniFile(const QString &iniFile)
{
//如果配置文件大小为0,则以初始值继续运行,并生成配置文件
QFile file(iniFile);
if (file.size() == 0) {
return false;
}
//如果配置文件不完整,则以初始值继续运行,并生成配置文件
if (file.open(QFile::ReadOnly)) {
bool ok = true;
while (!file.atEnd()) {
QString line = file.readLine();
line.replace("\r", "");
line.replace("\n", "");
QStringList list = line.split("=");
if (list.count() == 2) {
if (list.at(1) == "") {
qDebug() << "ini node no value" << list.at(0);
ok = false;
break;
}
}
}
if (!ok) {
return false;
}
} else {
return false;
}
return true;
}

View File

@@ -0,0 +1,70 @@
#ifndef QUIHELPER2_H
#define QUIHELPER2_H
#include "head.h"
class QUIHelper
{
public:
//获取当前鼠标所在屏幕索引+尺寸
static int getScreenIndex();
static QRect getScreenRect(bool available = true);
//获取桌面宽度高度+居中显示
static int deskWidth();
static int deskHeight();
//居中显示窗体
//定义标志位指定是以桌面为参照还是主程序界面为参照
static QWidget *centerBaseForm;
static void setFormInCenter(QWidget *form);
//程序文件名称+当前所在路径
static QString appName();
static QString appPath();
//获取uuid+初始化随机数种子+新建目录+延时
static QString getUuid();
static void initRand();
static void newDir(const QString &dirName);
static void sleep(int msec);
//设置样式+字体+编码+居中+翻译
static void setStyle();
static void setFont(int fontSize = 12);
static void setCode(bool utf8 = true);
static void setTranslator(const QString &qmFile);
//一次性设置所有
static void initAll();
//设置无边框
static void setFramelessForm(QWidget *widgetMain, bool tool = false, bool top = false, bool menu = true);
//弹出框
static int showMessageBox(const QString &info, int type = 0, int closeSec = 0, bool exec = false);
//弹出消息框
static void showMessageBoxInfo(const QString &info, int closeSec = 0, bool exec = false);
//弹出错误框
static void showMessageBoxError(const QString &info, int closeSec = 0, bool exec = false);
//弹出询问框
static int showMessageBoxQuestion(const QString &info);
//异或加密-只支持字符,如果是中文需要将其转换base64编码
static QString getXorEncryptDecrypt(const QString &value, char key);
//异或校验
static uchar getOrCode(const QByteArray &data);
//计算校验码
static uchar getCheckCode(const QByteArray &data);
//初始化表格
static void initTableView(QTableView *tableView, int rowHeight = 25,
bool headVisible = false, bool edit = false,
bool stretchLast = true);
//打开文件带提示框
static void openFile(const QString &fileName, const QString &msg);
//检查ini配置文件
static bool checkIniFile(const QString &iniFile);
};
#endif // QUIHELPER2_H

View File

@@ -0,0 +1,450 @@
#include "quihelperdata.h"
#include "quihelper.h"
int QUIHelperData::strHexToDecimal(const QString &strHex)
{
bool ok;
return strHex.toInt(&ok, 16);
}
int QUIHelperData::strDecimalToDecimal(const QString &strDecimal)
{
bool ok;
return strDecimal.toInt(&ok, 10);
}
int QUIHelperData::strBinToDecimal(const QString &strBin)
{
bool ok;
return strBin.toInt(&ok, 2);
}
QString QUIHelperData::strHexToStrBin(const QString &strHex)
{
uchar decimal = strHexToDecimal(strHex);
QString bin = QString::number(decimal, 2);
uchar len = bin.length();
if (len < 8) {
for (int i = 0; i < 8 - len; i++) {
bin = "0" + bin;
}
}
return bin;
}
QString QUIHelperData::decimalToStrBin1(int decimal)
{
QString bin = QString::number(decimal, 2);
uchar len = bin.length();
if (len <= 8) {
for (int i = 0; i < 8 - len; i++) {
bin = "0" + bin;
}
}
return bin;
}
QString QUIHelperData::decimalToStrBin2(int decimal)
{
QString bin = QString::number(decimal, 2);
uchar len = bin.length();
if (len <= 16) {
for (int i = 0; i < 16 - len; i++) {
bin = "0" + bin;
}
}
return bin;
}
QString QUIHelperData::decimalToStrHex(int decimal)
{
QString temp = QString::number(decimal, 16);
if (temp.length() == 1) {
temp = "0" + temp;
}
return temp;
}
QByteArray QUIHelperData::intToByte(int data)
{
QByteArray result;
result.resize(4);
result[3] = (uchar)(0x000000ff & data);
result[2] = (uchar)((0x0000ff00 & data) >> 8);
result[1] = (uchar)((0x00ff0000 & data) >> 16);
result[0] = (uchar)((0xff000000 & data) >> 24);
return result;
}
QByteArray QUIHelperData::intToByteRec(int data)
{
QByteArray result;
result.resize(4);
result[0] = (uchar)(0x000000ff & data);
result[1] = (uchar)((0x0000ff00 & data) >> 8);
result[2] = (uchar)((0x00ff0000 & data) >> 16);
result[3] = (uchar)((0xff000000 & data) >> 24);
return result;
}
int QUIHelperData::byteToInt(const QByteArray &data)
{
int i = data.at(3) & 0x000000ff;
i |= ((data.at(2) << 8) & 0x0000ff00);
i |= ((data.at(1) << 16) & 0x00ff0000);
i |= ((data.at(0) << 24) & 0xff000000);
return i;
}
int QUIHelperData::byteToIntRec(const QByteArray &data)
{
int i = data.at(0) & 0x000000ff;
i |= ((data.at(1) << 8) & 0x0000ff00);
i |= ((data.at(2) << 16) & 0x00ff0000);
i |= ((data.at(3) << 24) & 0xff000000);
return i;
}
quint32 QUIHelperData::byteToUInt(const QByteArray &data)
{
quint32 i = data.at(3) & 0x000000ff;
i |= ((data.at(2) << 8) & 0x0000ff00);
i |= ((data.at(1) << 16) & 0x00ff0000);
i |= ((data.at(0) << 24) & 0xff000000);
return i;
}
quint32 QUIHelperData::byteToUIntRec(const QByteArray &data)
{
quint32 i = data.at(0) & 0x000000ff;
i |= ((data.at(1) << 8) & 0x0000ff00);
i |= ((data.at(2) << 16) & 0x00ff0000);
i |= ((data.at(3) << 24) & 0xff000000);
return i;
}
QByteArray QUIHelperData::ushortToByte(ushort data)
{
QByteArray result;
result.resize(2);
result[1] = (uchar)(0x000000ff & data);
result[0] = (uchar)((0x0000ff00 & data) >> 8);
return result;
}
QByteArray QUIHelperData::ushortToByteRec(ushort data)
{
QByteArray result;
result.resize(2);
result[0] = (uchar)(0x000000ff & data);
result[1] = (uchar)((0x0000ff00 & data) >> 8);
return result;
}
int QUIHelperData::byteToUShort(const QByteArray &data)
{
int i = data.at(1) & 0x000000FF;
i |= ((data.at(0) << 8) & 0x0000FF00);
if (i >= 32768) {
i = i - 65536;
}
return i;
}
int QUIHelperData::byteToUShortRec(const QByteArray &data)
{
int i = data.at(0) & 0x000000FF;
i |= ((data.at(1) << 8) & 0x0000FF00);
if (i >= 32768) {
i = i - 65536;
}
return i;
}
QString QUIHelperData::getValue(quint8 value)
{
QString result = QString::number(value);
if (result.length() <= 1) {
result = QString("0%1").arg(result);
}
return result;
}
QString QUIHelperData::getXorEncryptDecrypt(const QString &value, char key)
{
//矫正范围外的数据
if (key < 0 || key >= 127) {
key = 127;
}
QString result = value;
int count = result.count();
for (int i = 0; i < count; i++) {
result[i] = QChar(result.at(i).toLatin1() ^ key);
}
return result;
}
uchar QUIHelperData::getOrCode(const QByteArray &data)
{
int len = data.length();
uchar result = 0;
for (int i = 0; i < len; i++) {
result ^= data.at(i);
}
return result;
}
uchar QUIHelperData::getCheckCode(const QByteArray &data)
{
int len = data.length();
uchar temp = 0;
for (uchar i = 0; i < len; i++) {
temp += data.at(i);
}
return temp % 256;
}
//函数功能计算CRC16
//参数1*data 16位CRC校验数据
//参数2len 数据流长度
//参数3init 初始化值
//参数4table 16位CRC查找表
//正序CRC计算
quint16 QUIHelperData::getCrc16(quint8 *data, int len, quint16 init, const quint16 *table)
{
quint16 crc_16 = init;
quint8 temp;
while (len-- > 0) {
temp = crc_16 & 0xff;
crc_16 = (crc_16 >> 8) ^ table[(temp ^ *data++) & 0xff];
}
return crc_16;
}
//逆序CRC计算
quint16 QUIHelperData::getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table)
{
quint16 crc_16 = init;
quint8 temp;
while (len-- > 0) {
temp = crc_16 >> 8;
crc_16 = (crc_16 << 8) ^ table[(temp ^ *data++) & 0xff];
}
return crc_16;
}
//Modbus CRC16校验
quint16 QUIHelperData::getModbus16(quint8 *data, int len)
{
//MODBUS CRC-16表 8005 逆序
const quint16 table_16[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
return getCrc16(data, len, 0xFFFF, table_16);
}
//CRC16校验
QByteArray QUIHelperData::getCrcCode(const QByteArray &data)
{
quint16 result = getModbus16((quint8 *)data.data(), data.length());
return QUIHelperData::ushortToByteRec(result);
}
static QMap<char, QString> listChar;
void QUIHelperData::initAscii()
{
//0x20为空格,空格以下都是不可见字符
if (listChar.count() == 0) {
listChar.insert(0, "\\NUL");
listChar.insert(1, "\\SOH");
listChar.insert(2, "\\STX");
listChar.insert(3, "\\ETX");
listChar.insert(4, "\\EOT");
listChar.insert(5, "\\ENQ");
listChar.insert(6, "\\ACK");
listChar.insert(7, "\\BEL");
listChar.insert(8, "\\BS");
listChar.insert(9, "\\HT");
listChar.insert(10, "\\LF");
listChar.insert(11, "\\VT");
listChar.insert(12, "\\FF");
listChar.insert(13, "\\CR");
listChar.insert(14, "\\SO");
listChar.insert(15, "\\SI");
listChar.insert(16, "\\DLE");
listChar.insert(17, "\\DC1");
listChar.insert(18, "\\DC2");
listChar.insert(19, "\\DC3");
listChar.insert(20, "\\DC4");
listChar.insert(21, "\\NAK");
listChar.insert(22, "\\SYN");
listChar.insert(23, "\\ETB");
listChar.insert(24, "\\CAN");
listChar.insert(25, "\\EM");
listChar.insert(26, "\\SUB");
listChar.insert(27, "\\ESC");
listChar.insert(28, "\\FS");
listChar.insert(29, "\\GS");
listChar.insert(30, "\\RS");
listChar.insert(31, "\\US");
listChar.insert(0x5C, "\\");
listChar.insert(0x7F, "\\DEL");
}
}
QString QUIHelperData::byteArrayToAsciiStr(const QByteArray &data)
{
//先初始化字符表
initAscii();
QString temp;
int len = data.size();
for (int i = 0; i < len; i++) {
char byte = data.at(i);
QString value = listChar.value(byte);
if (!value.isEmpty()) {
} else if (byte >= 0 && byte <= 0x7F) {
value = QString("%1").arg(byte);
} else {
value = decimalToStrHex((quint8)byte);
value = QString("\\x%1").arg(value.toUpper());
}
temp += value;
}
return temp.trimmed();
}
QByteArray QUIHelperData::asciiStrToByteArray(const QString &data)
{
//先初始化字符表
initAscii();
QByteArray buffer;
QStringList list = data.split("\\");
int count = list.count();
for (int i = 1; i < count; i++) {
QString str = list.at(i);
int key = 0;
if (str.contains("x")) {
key = strHexToDecimal(str.mid(1, 2));
} else {
key = listChar.key("\\" + str);
}
buffer.append(key);
}
return buffer;
}
char QUIHelperData::hexStrToChar(char data)
{
if ((data >= '0') && (data <= '9')) {
return data - 0x30;
} else if ((data >= 'A') && (data <= 'F')) {
return data - 'A' + 10;
} else if ((data >= 'a') && (data <= 'f')) {
return data - 'a' + 10;
} else {
return (-1);
}
}
QByteArray QUIHelperData::hexStrToByteArray(const QString &data)
{
QByteArray senddata;
int hexdata, lowhexdata;
int hexdatalen = 0;
int len = data.length();
senddata.resize(len / 2);
char lstr, hstr;
for (int i = 0; i < len;) {
hstr = data.at(i).toLatin1();
if (hstr == ' ') {
i++;
continue;
}
i++;
if (i >= len) {
break;
}
lstr = data.at(i).toLatin1();
hexdata = hexStrToChar(hstr);
lowhexdata = hexStrToChar(lstr);
if ((hexdata == 16) || (lowhexdata == 16)) {
break;
} else {
hexdata = hexdata * 16 + lowhexdata;
}
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
return senddata;
}
QString QUIHelperData::byteArrayToHexStr(const QByteArray &data)
{
QString temp = "";
QString hex = data.toHex();
for (int i = 0; i < hex.length(); i = i + 2) {
temp += hex.mid(i, 2) + " ";
}
return temp.trimmed().toUpper();
}

View File

@@ -0,0 +1,70 @@
#ifndef QUIHELPERDATA_H
#define QUIHELPERDATA_H
#include <QObject>
class QUIHelperData
{
public:
//16进制字符串转10进制
static int strHexToDecimal(const QString &strHex);
//10进制字符串转10进制
static int strDecimalToDecimal(const QString &strDecimal);
//2进制字符串转10进制
static int strBinToDecimal(const QString &strBin);
//16进制字符串转2进制字符串
static QString strHexToStrBin(const QString &strHex);
//10进制转2进制字符串一个字节
static QString decimalToStrBin1(int decimal);
//10进制转2进制字符串两个字节
static QString decimalToStrBin2(int decimal);
//10进制转16进制字符串,补零.
static QString decimalToStrHex(int decimal);
//int转字节数组
static QByteArray intToByte(int data);
static QByteArray intToByteRec(int data);
//字节数组转int
static int byteToInt(const QByteArray &data);
static int byteToIntRec(const QByteArray &data);
static quint32 byteToUInt(const QByteArray &data);
static quint32 byteToUIntRec(const QByteArray &data);
//ushort转字节数组
static QByteArray ushortToByte(ushort data);
static QByteArray ushortToByteRec(ushort data);
//字节数组转ushort
static int byteToUShort(const QByteArray &data);
static int byteToUShortRec(const QByteArray &data);
//字符串补全
static QString getValue(quint8 value);
//异或加密-只支持字符,如果是中文需要将其转换base64编码
static QString getXorEncryptDecrypt(const QString &value, char key);
//异或校验
static uchar getOrCode(const QByteArray &data);
//计算校验码
static uchar getCheckCode(const QByteArray &data);
//CRC校验
static quint16 getCrc16Rec(quint8 *data, int len, quint16 init, const quint16 *table);
static quint16 getCrc16(quint8 *data, int len, quint16 init, const quint16 *table);
static quint16 getModbus16(quint8 *data, int len);
static QByteArray getCrcCode(const QByteArray &data);
//字节数组与Ascii字符串互转
static void initAscii();
static QString byteArrayToAsciiStr(const QByteArray &data);
static QByteArray asciiStrToByteArray(const QString &data);
//16进制字符串与字节数组互转
static char hexStrToChar(char data);
static QByteArray hexStrToByteArray(const QString &data);
static QString byteArrayToHexStr(const QByteArray &data);
};
#endif // QUIHELPERDATA_H

View File

@@ -0,0 +1,96 @@
#include "tcpclient.h"
#include "quihelper.h"
#include "quihelperdata.h"
TcpClient::TcpClient(QTcpSocket *socket, QObject *parent) : QObject(parent)
{
this->socket = socket;
ip = socket->peerAddress().toString();
ip = ip.replace("::ffff:", "");
port = socket->peerPort();
connect(socket, SIGNAL(disconnected()), this, SLOT(slot_disconnected()));
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(slot_error()));
#else
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slot_error()));
#endif
connect(socket, SIGNAL(readyRead()), this, SLOT(slot_readData()));
}
QString TcpClient::getIP() const
{
return this->ip;
}
int TcpClient::getPort() const
{
return this->port;
}
void TcpClient::slot_disconnected()
{
emit disconnected(ip, port);
socket->deleteLater();
this->deleteLater();
}
void TcpClient::slot_error()
{
emit error(ip, port, socket->errorString());
}
void TcpClient::slot_readData()
{
QByteArray data = socket->readAll();
if (data.length() <= 0) {
return;
}
QString buffer;
if (AppConfig::HexReceiveTcpServer) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else if (AppConfig::AsciiTcpServer) {
buffer = QUIHelperData::byteArrayToAsciiStr(data);
} else {
buffer = QString(data);
}
emit receiveData(ip, port, buffer);
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
if (AppConfig::DebugTcpServer) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(AppData::Values.at(i));
break;
}
}
}
}
void TcpClient::sendData(const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendTcpServer) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else if (AppConfig::AsciiTcpServer) {
buffer = QUIHelperData::asciiStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
socket->write(buffer);
emit sendData(ip, port, data);
}
void TcpClient::disconnectFromHost()
{
socket->disconnectFromHost();
}
void TcpClient::abort()
{
socket->abort();
}

View File

@@ -0,0 +1,46 @@
#ifndef TCPCLIENT_H
#define TCPCLIENT_H
#include <QtNetwork>
//为了方便并发和单独处理数据所以单独写个类专门处理
#if 1
//小数据量可以不用线程,收发数据本身默认异步的
class TcpClient : public QObject
#else
//线程方便处理密集运算比如解析图片
class TcpClient : public QThread
#endif
{
Q_OBJECT
public:
explicit TcpClient(QTcpSocket *socket, QObject *parent = 0);
private:
QTcpSocket *socket;
QString ip;
int port;
public:
QString getIP() const;
int getPort() const;
private slots:
void slot_disconnected();
void slot_error();
void slot_readData();
signals:
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
public slots:
void sendData(const QString &data);
void disconnectFromHost();
void abort();
};
#endif // TCPCLIENT_H

View File

@@ -0,0 +1,75 @@
#include "tcpserver.h"
#include "quihelper.h"
TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
{
connect(this, SIGNAL(newConnection()), this, SLOT(slot_newConnection()));
}
void TcpServer::slot_newConnection()
{
QTcpSocket *socket = this->nextPendingConnection();
TcpClient *client = new TcpClient(socket, this);
connect(client, SIGNAL(disconnected(QString, int)), this, SLOT(slot_disconnected(QString, int)));
connect(client, SIGNAL(error(QString, int, QString)), this, SIGNAL(error(QString, int, QString)));
connect(client, SIGNAL(sendData(QString, int, QString)), this, SIGNAL(sendData(QString, int, QString)));
connect(client, SIGNAL(receiveData(QString, int, QString)), this, SIGNAL(receiveData(QString, int, QString)));
emit connected(client->getIP(), client->getPort());
//连接后加入链表
clients.append(client);
}
void TcpServer::slot_disconnected(const QString &ip, int port)
{
TcpClient *client = (TcpClient *)sender();
emit disconnected(ip, port);
//断开连接后从链表中移除
clients.removeOne(client);
}
bool TcpServer::start()
{
bool ok = listen(QHostAddress(AppConfig::TcpListenIP), AppConfig::TcpListenPort);
return ok;
}
void TcpServer::stop()
{
remove();
this->close();
}
void TcpServer::writeData(const QString &ip, int port, const QString &data)
{
foreach (TcpClient *client, clients) {
if (client->getIP() == ip && client->getPort() == port) {
client->sendData(data);
break;
}
}
}
void TcpServer::writeData(const QString &data)
{
foreach (TcpClient *client, clients) {
client->sendData(data);
}
}
void TcpServer::remove(const QString &ip, int port)
{
foreach (TcpClient *client, clients) {
if (client->getIP() == ip && client->getPort() == port) {
client->abort();
break;
}
}
}
void TcpServer::remove()
{
foreach (TcpClient *client, clients) {
client->abort();
}
}

View File

@@ -0,0 +1,44 @@
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include "tcpclient.h"
class TcpServer : public QTcpServer
{
Q_OBJECT
public:
explicit TcpServer(QObject *parent = 0);
private:
QList<TcpClient *> clients;
private slots:
void slot_newConnection();
void slot_disconnected(const QString &ip, int port);
signals:
void connected(const QString &ip, int port);
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
public slots:
//启动服务
bool start();
//停止服务
void stop();
//指定连接发送数据
void writeData(const QString &ip, int port, const QString &data);
//对所有连接发送数据
void writeData(const QString &data);
//断开指定连接
void remove(const QString &ip, int port);
//断开所有连接
void remove();
};
#endif // TCPSERVER_H

View File

@@ -0,0 +1,105 @@
#include "webclient.h"
#include "quihelper.h"
#include "quihelperdata.h"
WebClient::WebClient(QWebSocket *socket, QObject *parent) : QObject(parent)
{
this->socket = socket;
ip = socket->peerAddress().toString();
ip = ip.replace("::ffff:", "");
port = socket->peerPort();
connect(socket, SIGNAL(disconnected()), this, SLOT(slot_disconnected()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slot_error()));
//暂时使用前面两个信号,部分系统后面两个信号Qt没实现,目前测试到5.15.2
//在win上如果两组信号都关联了则都会触发,另外一组信号就是多个参数表示是否是最后一个数据包
connect(socket, SIGNAL(textMessageReceived(QString)), this, SLOT(textMessageReceived(QString)));
connect(socket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(binaryMessageReceived(QByteArray)));
//connect(socket, SIGNAL(textFrameReceived(QString, bool)), this, SLOT(textFrameReceived(QString, bool)));
//connect(socket, SIGNAL(binaryFrameReceived(QByteArray, bool)), this, SLOT(binaryFrameReceived(QByteArray, bool)));
}
QString WebClient::getIP() const
{
return this->ip;
}
int WebClient::getPort() const
{
return this->port;
}
void WebClient::slot_disconnected()
{
emit disconnected(ip, port);
socket->deleteLater();
this->deleteLater();
}
void WebClient::slot_error()
{
emit error(ip, port, socket->errorString());
}
void WebClient::textFrameReceived(const QString &data, bool isLastFrame)
{
QString buffer = data;
emit receiveData(ip, port, buffer);
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
if (AppConfig::DebugWebServer) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(AppData::Values.at(i));
break;
}
}
}
}
void WebClient::binaryFrameReceived(const QByteArray &data, bool isLastFrame)
{
QString buffer;
if (AppConfig::HexReceiveWebClient) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else {
buffer = QString(data);
}
textFrameReceived(buffer, isLastFrame);
}
void WebClient::textMessageReceived(const QString &data)
{
textFrameReceived(data, true);
}
void WebClient::binaryMessageReceived(const QByteArray &data)
{
binaryFrameReceived(data, true);
}
void WebClient::sendData(const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendWebServer) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
if (AppConfig::AsciiWebServer) {
socket->sendTextMessage(data);
} else {
socket->sendBinaryMessage(buffer);
}
emit sendData(ip, port, data);
}
void WebClient::abort()
{
socket->abort();
}

View File

@@ -0,0 +1,49 @@
#ifndef WEBCLIENT_H
#define WEBCLIENT_H
#include <QtWebSockets>
//为了方便并发和单独处理数据所以单独写个类专门处理
#if 1
//小数据量可以不用线程,收发数据本身默认异步的
class WebClient : public QObject
#else
//线程方便处理密集运算比如解析图片
class WebClient : public QThread
#endif
{
Q_OBJECT
public:
explicit WebClient(QWebSocket *socket, QObject *parent = 0);
private:
QWebSocket *socket;
QString ip;
int port;
public:
QString getIP() const;
int getPort() const;
private slots:
void slot_disconnected();
void slot_error();
void textFrameReceived(const QString &data, bool isLastFrame);
void binaryFrameReceived(const QByteArray &data, bool isLastFrame);
void textMessageReceived(const QString &data);
void binaryMessageReceived(const QByteArray &data);
signals:
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
public slots:
void sendData(const QString &data);
void abort();
};
#endif // WEBCLIENT_H

View File

@@ -0,0 +1,75 @@
#include "webserver.h"
#include "quihelper.h"
WebServer::WebServer(const QString &serverName, SslMode secureMode, QObject *parent) : QWebSocketServer(serverName, secureMode, parent)
{
connect(this, SIGNAL(newConnection()), this, SLOT(slot_newConnection()));
}
void WebServer::slot_newConnection()
{
QWebSocket *socket = this->nextPendingConnection();
WebClient *client = new WebClient(socket, this);
connect(client, SIGNAL(disconnected(QString, int)), this, SLOT(slot_disconnected(QString, int)));
connect(client, SIGNAL(error(QString, int, QString)), this, SIGNAL(error(QString, int, QString)));
connect(client, SIGNAL(sendData(QString, int, QString)), this, SIGNAL(sendData(QString, int, QString)));
connect(client, SIGNAL(receiveData(QString, int, QString)), this, SIGNAL(receiveData(QString, int, QString)));
emit connected(client->getIP(), client->getPort());
//连接后加入链表
clients.append(client);
}
void WebServer::slot_disconnected(const QString &ip, int port)
{
WebClient *client = (WebClient *)sender();
emit disconnected(ip, port);
//断开连接后从链表中移除
clients.removeOne(client);
}
bool WebServer::start()
{
bool ok = listen(QHostAddress(AppConfig::WebListenIP), AppConfig::WebListenPort);
return ok;
}
void WebServer::stop()
{
remove();
this->close();
}
void WebServer::writeData(const QString &ip, int port, const QString &data)
{
foreach (WebClient *client, clients) {
if (client->getIP() == ip && client->getPort() == port) {
client->sendData(data);
break;
}
}
}
void WebServer::writeData(const QString &data)
{
foreach (WebClient *client, clients) {
client->sendData(data);
}
}
void WebServer::remove(const QString &ip, int port)
{
foreach (WebClient *client, clients) {
if (client->getIP() == ip && client->getPort() == port) {
client->abort();
break;
}
}
}
void WebServer::remove()
{
foreach (WebClient *client, clients) {
client->abort();
}
}

View File

@@ -0,0 +1,44 @@
#ifndef WEBSERVER_H
#define WEBSERVER_H
#include "webclient.h"
class WebServer : public QWebSocketServer
{
Q_OBJECT
public:
explicit WebServer(const QString &serverName = QString(), QWebSocketServer::SslMode secureMode = QWebSocketServer::NonSecureMode, QObject *parent = 0);
private:
QList<WebClient *> clients;
private slots:
void slot_newConnection();
void slot_disconnected(const QString &ip, int port);
signals:
void connected(const QString &ip, int port);
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
public slots:
//启动服务
bool start();
//停止服务
void stop();
//指定连接发送数据
void writeData(const QString &ip, int port, const QString &data);
//对所有连接发送数据
void writeData(const QString &data);
//断开指定连接
void remove(const QString &ip, int port);
//断开所有连接
void remove();
};
#endif // WEBSERVER_H

View File

@@ -0,0 +1,20 @@
2015;\NUL2015
666;667
3001P;301PST1:hehe'2:P2'3:P3'
3002P;301PST
3003P;301PST
3004P;301PST
3005P;301PST
326;00110
320;00101
330010;00101
331;332001
568X;5691:0
5700;5710:10:1;2;3
330051;00101
112P001000I1';113P001100I1'101I1'102B0'103B0'106B0'107I0'108I1'109I0'110R1.750000'111R6.300000'112R1.500000'113R3.100000'114R4.500000'115R1.050000'116R7.000000'117R9999.000000'118I0'119R3.500000'120R1.750000'121I1'122I0'123I0'124I70'130I1000'131I8000'132I1500'133I10000'134I10'135I5'136I20'137I40'140R0.000000'105B1'138I700'104I0'125I0'126I9999'141R0.200000'142R0.200000'143R0.000000'144R30.000000'150I1'151I10'152B0'153I0'160I0'200B0'210B0'211I1'212I1'213R1.050000'214R9999.000000'220B0'221I0'222I1'223I1'224R1.050000'225R7.000000'230B0'240I0'241B1'242B0'243B0'244B0'245R100.000000'246B0'260R0.000000'261I0'262I0'263I50'264I0'280B0'281R1.050000'282I9999'283I1'284R7.000000'285I1'286I1'290I0'291R9999.000000'292R9999.000000'293I10'294I150'295I0'402Shehe'406I1433082933'500R0.000000'501R9999.000000'502I4'503I10'504I1'505I30'506B0'510R0.000000'511R9999.000000'512R0.000000'513R9999.000000'514R0.000000'515R0.000000'507B0'520I0'521I9999'522I0'523I9999'524I0'525I0'508B0'560R0.000000'561R9999.000000'562R0.000000'563R9999.000000'564R0.000000'565R0.000000'530I0'531I9999'532I0'533I9999'534I0'535I0'540R0.000000'541R9999.000000'542R0.000000'543R9999.000000'544R0.000000'545R0.000000'550R0.000000'551R9999.000000'552R0.000000'553R9999.000000'554R0.000000'555R0.000000'
302P001;00101
002;003\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL
112R000;113R001100R2.530000'101I1'102I23'103I1'104I0'105I0'106I3'107B1'108I0'109I2'110R0.000000'111I1'116R0.000000'117R0.000000'118I1'120I0'121I1'122R0.000000'123I1'300I186'301S2015-06-01'302S15:53:56'303S'305S359194'311I0'312I0'313I0'314I1'319I0'340I1'341I0'351SGUT'360S'361S'362S'
126;123G100I00186'101S2015-06-01'102S15:53:56'103S'104S0'105S359194'106I00000'107I00000'110I00000'111I00000'112I00000'113I00000'114I00001'115I00000'116I00000'200I00003'201R00001.50'202I00000'203I01060'204I1638400'205I00001'206R00002.50'210R00002.20'211R00002.80'212R00000.00'213R00000.00'214R00000.42'215R09999.00'216R00000.42'217R00002.80'218R00000.00'219R00000.00'230R00000.42'231R00002.80'232R00002.53';\ETX\xA6\EOT]\ENQI\ACK{\x08\ETX\x07\xB0\ENQ\xEA\NUL\xD8\xFF\x9F\xFF\x7F\xFF\xC3\xFF\xFC\xFF\x10\xFF\xC1\NUL\EOT\xFF\xFC\NUL\CR\SOH\CR\SOH\xB4\SOH\xC2\SOH\xC8\SOH\xC8\SOH\xA6\SOH\x94\SOH\xA8\SOH\xC6\SOH\xD8\SOH\xDC\SOH\xDA\SOH\xD8\SOH\xDA\SOH\xDA\SOH\xDC\SOH\xDC\SOH\xE4\SOH\xEC\SOH\xF4\STX\NUL\STX\LF\STX\x12\STX\x12\STX\x16\STX\x14\STX\x10\STX\x08\SOH\xE8\SOH\x98\SOH-\NUL\xE1\NUL\xA2\NUL\x86\NUL\x86\NUL\x96\NUL\xA8\NUL\xBF\NUL\xDD\NUL\xFF\SOH\x1D\SOH?\SOH_\SOHz\SOH\x98\SOH\xB4\SOH\xCC\SOH\xE4\SOH\xFA\STX\NUL\STX\ACK\STX\x08\STX\x0C\STX\ACK\STX\STX\SOH\xFE\SOH\xF6\SOH\xF4\SOH\xF6\SOH\xFA\STX\STX\STX\x0E\STX\x16\STX\x19\STX\x19\STX\ESC\STX\x1F\STX\x1F\STX\ESC\STX\x14\STX\x12\STX\x16\STX\ESC\STX%\STX3\STXA\STXC\STXG\STXM\STXO\STXO\STXO\STXO\STXO\STXU\STXU\STX]\STXe\STXq\STXw\STXy\STX\x7F\STX\x7F\STX\x81\STX\x85\STX\x83\STX\x83\STX\x87\STX\x8B\STX\x95\STX\xA7\STX\xBB\STX\xCE\STX\xD8\STX\xE6\STX\xF8\ETX\x10\ETX$\ETX:\ETXP\ETXn\ETX\x8F\ETX\xB3\ETX\xDD\EOT\x07\EOT+\EOTN\EOTh\EOT\x84\EOT\xA0\EOT\xBA\EOT\xD4\EOT\xE7\EOT\xF9\ENQ\x0F\ENQ)\ENQG\ENQi\ENQ\x95\ENQ\xB4\ENQ\xD0\ENQ\xEC\ACK\x0C\ACK(\ACKF\ACK[\ACKm\ACK}\ACK\x93\ACK\xA3\ACK\xBD\ACK\xDD\x07\STX\x07"\x07D\x07h\x07\x86\x07\x9E\x07\xB7\x07\xC7\x07\xD5\x07\xE5\x07\xFB\x08\ESC\x08C\x08p\x08\x8E\x08\xA6\x08\xB8\x08\xC2\x08\xCC\x08\xDA\x08\xE6\x08\xF4\x09\ACK\x09\x19\x09-\x09G\x09c\x09y\x09\x8B\x09\xA3\x09\xB9\x09\xC8\x09\xDA\x09\xE8\x09\xF8\LF\x10\LF(\LFB\LF^\LF\x81\LF\x9D\LF\xB3\LF\xCB\LF\xE5\LF\xFD\x0B\x13\x0B,\x0B>\x0BX\x0Br\x0B\x90\x0B\xAE\x0B\xCC\x0B\xED\x0C\x09\x0C%\x0CE\x0Ce\x0C}\x0C\x92\x0C\xA8\x0C\xBC\x0C\xD4\x0C\xEE\CR\x0C\CR,\CRO\CRk\CR\x87\CR\xA3\CR\xBD\CR\xD5\CR\xF0\x0E\ACK\x0E\x1C\x0E4\x0ER\x0En\x0E\x90\x0E\xB9\x0E\xDF\x0E\xFF\x0F\x1D\x0F?\x0F%\x0E\xB6\CR\xC3\x0C\x1F\LF:\x08e\ACK\xD3\ENQ\xA3\ENQ\x11\ENQE\ACK$\x07`\x08\x8F\x09}\LF\x12\LFV\LFb\LFH\LF\x16\x09\xDA\x09\x9D\x09k\x09C\x09\x16\x08\xF0\x08\xD8\x08\xC4\x08\xB4\x08\xAE\x08\xAE\x08\xB4\x08\xC0\x08\xC4\x08\xC2\x08\xB2\x08\xA4\x08\x94\x08x\x08Q\x08)\x07\xFB\x07\xD1\x07\xB3\x07\x98\x07\x82\x07h\x07N\x07B\x07B\x07D\x07@\x074\x07$\x07\x12\ACK\xF9\ACK\xDD\ACK\xBF\ACK\xA5\ACK\x93\ACK\x87\ACKy\ACKi\ACK[\ACKM\ACK:\ACK$\ACK\x08\ENQ\xE4\ENQ\xCC\ENQ\xB6\ENQ\xA0\ENQ\x83\ENQk\ENQY\ENQM\ENQM\ENQM\ENQK\ENQE\ENQA\ENQ?\ENQ5\ENQ%\ENQ\x11\ENQ\SOH\EOT\xF7\EOT\xEB\EOT\xE7\EOT\xE7\EOT\xED\EOT\xED\EOT\xEB\EOT\xE3\EOT\xD6\EOT\xCE\EOT\xCE\EOT\xC8\EOT\xBE\EOT\xB4\EOT\xAC\EOT\xA4\EOT\xAA\EOT\xA8\EOT\x9E\EOT\x94\EOT\x8C\EOT\x80\EOTn\EOTT\EOT8\EOT\x17\ETX\xFF\ETX\xE9\ETX\xD1\ETX\xC5\ETX\xB5\ETX\xA7\ETX\x8F\ETXx\ETX\\\ETX>\ETX$\ETX\x0E\STX\xE8\STX\xC5\STX\xA5\STX\x91\STX\x7F\STXm\STX]\STXG\STX-\STX\x1D\STX\x0C\SOH\xFA\SOH\xF0\SOH\xDE\SOH\xD0\SOH\xBE\SOH\xB2\SOH\xA4\SOH\x9A\SOH\x88\SOH~\SOHp\SOH]\SOHE\SOH3\SOH%\SOH\x17\SOH\ETX\NUL\xDF\NUL\xB0\NUL\x84\NULj\NULT\NUL>\NUL*\NUL\CAN\NUL\x0C\xFF\xFE\xFF\xF1\xFF\xE9\xFF\xE1\xFF\xE1\xFF\xE1\xFF\xE1\xFF\xE3\xFF\xEB\xFF\xEF\xFF\xF3\xFF\xF5\xFF\xF7\xFF\xF3\xFF\xF1\xFF\xEB\xFF\xE7\xFF\xE7\xFF\xE7\xFF\xE7\xFF\xE9\xFF\xEF\xFF\xF7\xFF\xF9\xFF\xFE\NUL\NUL\NUL\NUL\xFF\xFE\xFF\xF7\xFF\xF3\xFF\xED\xFF\xED\xFF\xED\xFF\xF3\xFF\xFC\NUL\EOT\NUL\x0C\NUL\x0E\NUL\x12\NUL\x12\NUL\x10\NUL\x08\NUL\STX\xFF\xFE\xFF\xF9\xFF\xF9\xFF\xF9\NUL\NUL\NUL\ACK\NUL\x0C\NUL\x12\NUL\x12\NUL\x10\NUL\LF\NUL\STX\xFF\xF9\xFF\xF3\xFF\xF3\xFF\xED\xFF\xED\xFF\xF1\xFF\xF7\xFF\xFE\NUL\EOT\NUL\ACK\NUL\ACK\NUL\EOT\xFF\xFA\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xF9\xFF\xFC\xFF\xF9\xFF\xF9\xFF\xF9\xFF\xFE\xFF\xF9\xFF\xF5\xFF\xEF\xFF\xE9\xFF\xE5\xFF\xE1\xFF\xE1\xFF\xE9\xFF\xED\xFF\xF5\xFF\xF9\xFF\xF9\NUL\NUL\xFF\xFE\xFF\xF9\xFF\xF3\xFF\xF3\xFF\xF3\xFF\xEF\xFF\xF3\xFF\xF5\xFF\xFE\NUL\EOT\NUL\ACK\NUL\ACK\NUL\ACK\NUL\ACK\NUL\ACK\NUL\NUL\xFF\xF9\xFF\xF3
127;125G100I00186'101S2015-06-01'102S15:53:56'103S'104S0'105S359194'106I00000'107I00000'110I00000'111I00000'112I00000'113I00000'114I00001'115I00000'116I00000'200I00003'201R00001.50'202I00000'203I36000'204I01979'205I08192'220I00002'221I09000'222I00000'223I09999'224I00771'225I00000'226I00001'227I00000'228I00001'229I00023'240I-9997'241I00001'242I00001'243I00001'244I00000'245I09998';\NUL\NUL\x08%\CR4\x111\NAK\xA6\CAN\ETX\x16\xD6\x14\CR\x0F\xBA\x0C\x12\x07\x85\EOT\xCB\ETX]\ETX\x80\EOT\x9E\ENQ\xE4\x07\x8B\x08\xCB\LFA\x0BM\x0Cq\CR:\x0E\x16\x0E\xAB\x0FM\x0F\xC1\x10>\x10\x93\x10\xF3\x115\x11}\x11\xAE\x11\xE3\x12\x08\x120\x12N\x12n\x12\x81\x12\x96\x12\xA4\x12\xB5\x12\xC1\x12\xCD\x12\xD4\x12\xD8\x12\xCA\x12\xA3\x12\x82\x12^\x12E\x12/\x12$\x12\x1A\x12\x13\x12\CR\x12\ACK\x11\xFF\x11\xF9\x11\xF0\x11\xE8\x11\xDE\x11\xDA\x11\xCF\x11\xC7\x11\xBC\x11\xB2\x11\xA8\x11\xA4\x11\x9E\x11\x9C\x11\x9C\x11\x9C\x11\x9D\x11\x9F\x11\x9F\x11\x9F\x11\xA0\x11\xA3\x11\xA7\x11\xA9\x11\xA9\x11\xAB\x11\xB2\x11\xBA\x11\xC3\x11\xCC\x11\xD7\x11\xE0\x11\xEB\x11\xF6\x12\ACK\x12\x11\x12"\x12/\x12@\x12M\x12b\x12r\x12\x86\x12\x9A\x12\xB3\x12\xC9\x12\xDD\x12\xF1\x13\x08\x13\x1C\x134\x13I\x13d\x13|\x13\x99\x13\xB3\x13\xD2\x13\xEC\x14\CR\x14%\x14F\x14_\x14\x7F\x14\x9A\x14\xBC\x14\xD9\x14\xFB\NAK\NAK\NAK7\NAKS\NAKw\NAK\x91\NAK\xB1\NAK\xC9\NAK\xE3\NAK\xF7\x16\x0F\x16"\x168\x16K\x16d\x16v\x16\x8D\x16\x9E\x16\xB2\x16\xC5\x16\xDE\x16\xF4\x17\x0E\x17"\x17>\x17T\x17u\x17\x91\x17\xB3\x17\xCF\x17\xEF\CAN\LF\CAN*\CAND\CANd\CAN\x7F\CAN\xA4\CAN\xC4\CAN\xEE\x19\x0F\x199\x19[\x19\x82\x19\xA3\x19\xC5\x19\xE1\x1A\ENQ\x1A#\x1AI\x1Al\x1A\x98\x1A\xBC\x1A\xE8\ESC\x0E\ESC>\ESCg\ESC\x9D\ESC\xCC\x1C\x08\x1C:\x1Cw\x1C\xAA\x1C\xE7\x1D\x17\x1DP\x1D~\x1D\xB8\x1D\xE8\x1E"\x1EO\x1E\x89\x1E\xBA\x1E\xF7\x1F(\x1Fj\x1F\xA1\x1F\xE2 \NAK Q \x82 \xBD \xEE!-!a!\xA5!\xDD"$"^"\xA7"\xDE###W#\x98#\xD0$\x1C$Y$\xA5$\xE4%4%v%\xC9&\x07&S&\x8F&\xD6'\x13'a'\x9F'\xEB(((y(\xBD)\x13)W)\xB0)\xF3*J*\x90*\xE4+-+\x81+\xAD+\xA5+}+\x1C*\xBF*:)\xD0)\\)!)\x11)\x1F)6)>)9)))\x0E(\xF7(\xD5(\xBE(\x9F(\x8B(t(c(P(?(,(\x1D(\x0B'\xFD'\xEC'\xDF'\xCE'\xC1'\xAE'\x9E'\x8B'|'j'Y'F'8'%'\x19'\LF&\xFF&\xEB&\xDC&\xCC&\xC1&\xB1&\xA5&\x94&\x88&w&j&Y&L&>&4&&&\x1C&\CR&\STX%\xF7%\xEE%\xDF%\xD1%\xC1%\xB7%\xAA%\x9E%\x89%{%j%]%O%C%6%+%\x1E%\x11%\NUL$\xF0$\xD8$\xC8$\xB2$\x9D$\x85$p$X$E$($\x0F#\xF1#\xDB#\xC0#\xA7#\x85#j#M#4#\x12"\xF6"\xD5"\xBA"\x9A"}"W":"\x12!\xF5!\xD0!\xB4!\x8F!r!Q!8!\x1A!\SOH \xE4 \xCC \xB3 \x9B } g L 6 \x1C \ENQ\x1F\xEA\x1F\xD3\x1F\xBA\x1F\xA5\x1F\x8B\x1Fv\x1F[\x1FF\x1F(\x1F\x13\x1E\xF4\x1E\xDB\x1E\xBF\x1E\xA9\x1E\x8F\x1Ew\x1E[\x1EB\x1E(\x1E\x12\x1D\xFB\x1D\xE5\x1D\xC4\x1D\xA5\x1Dz\x1DU\x1D(\x1D\x07\x1C\xDB\x1C\xBB\x1C\x95\x1Cx\x1CZ\x1CD\x1C*\x1C\x1C\x1C\LF\ESC\xFE\ESC\xF4\ESC\xEE\ESC\xEA\ESC\xE5\ESC\xE7\ESC\xE7\ESC\xE8\ESC\xEB\ESC\xF0\ESC\xF3\ESC\xF8\ESC\xFF\x1C\x08\x1C\x0B\x1C\x16\x1C\ESC\x1C#\x1C(\x1C/\x1C5\x1C<\x1C@\x1CH\x1CN\x1CT\x1CZ\x1Cb\x1Ce\x1Ck\x1Cp\x1Cv\x1Cy\x1C{\x1C{\x1Cx\x1Cv\x1Cr\x1Cq\x1Cp\x1Co\x1Co\x1Co\x1Co\x1Cp\x1Cq\x1Cq\x1Cq\x1Cq\x1Ct\x1Ct\x1Ct\x1Cv\x1Cs\x1Cu\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cv\x1Cw\x1Cx\x1Cz\x1Cz\x1C{\x1C{\x1C{\x1C{\x1C{\x1C}\x1C\x7F\x1C}\x1C~\x1C}\x1C}\x1C\x7F\x1C}\x1C}\x1C|\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{\x1C{

View File

@@ -0,0 +1,17 @@
16 FF 01 01 E0 E1
16 FF 01 01 E1 E2
16 01 02 DF BC 16 01 02 DF BC 16 01 02 DF BC 12 13 14 15
16 00 00 04 D0 F0 F1 65 C4
16 00 00 04 D0 05 AB 5A C4
16 01 10 02 F0 03 06 16 01 11 02 F0 03 06 16 01 12 02 F0 03 06 16 01 13 02 F0 03 06 16 01
14 02 F0 03 06 16 01 15 02 F0 03 06 16 01 16 02 F0 03 06
16 11 01 03 E8 01 10 0E
16 11 01 03 E8 01 12 10
16 11 01 03 E8 01 14 12
16 11 01 03 E8 01 15 13
DISARMEDALL
BURGLARY 012
BYPASS 012
DISARMED 012
16 00 01 01 D1 D3
16 01 11 11

View File

@@ -0,0 +1,28 @@
FORMS += $$PWD/frmmain.ui
FORMS += $$PWD/frmtcpclient.ui
FORMS += $$PWD/frmtcpserver.ui
FORMS += $$PWD/frmudpclient.ui
FORMS += $$PWD/frmudpserver.ui
HEADERS += $$PWD/frmmain.h
HEADERS += $$PWD/frmtcpclient.h
HEADERS += $$PWD/frmtcpserver.h
HEADERS += $$PWD/frmudpclient.h
HEADERS += $$PWD/frmudpserver.h
SOURCES += $$PWD/frmmain.cpp
SOURCES += $$PWD/frmtcpclient.cpp
SOURCES += $$PWD/frmtcpserver.cpp
SOURCES += $$PWD/frmudpclient.cpp
SOURCES += $$PWD/frmudpserver.cpp
contains(DEFINES, websocket) {
FORMS += $$PWD/frmwebclient.ui
FORMS += $$PWD/frmwebserver.ui
HEADERS += $$PWD/frmwebclient.h
HEADERS += $$PWD/frmwebserver.h
SOURCES += $$PWD/frmwebclient.cpp
SOURCES += $$PWD/frmwebserver.cpp
}

View File

@@ -0,0 +1,51 @@
#include "frmmain.h"
#include "ui_frmmain.h"
#include "quihelper.h"
#include "frmtcpclient.h"
#include "frmtcpserver.h"
#include "frmudpclient.h"
#include "frmudpserver.h"
#ifdef websocket
#include "frmwebclient.h"
#include "frmwebserver.h"
#endif
frmMain::frmMain(QWidget *parent) : QWidget(parent), ui(new Ui::frmMain)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
}
frmMain::~frmMain()
{
delete ui;
}
void frmMain::initForm()
{
ui->tabWidget->addTab(new frmTcpClient, "TCP客户端");
ui->tabWidget->addTab(new frmTcpServer, "TCP服务端");
ui->tabWidget->addTab(new frmUdpClient, "UDP客户端");
ui->tabWidget->addTab(new frmUdpServer, "UDP服务端");
#ifdef websocket
ui->tabWidget->addTab(new frmWebClient, "WEB客户端");
ui->tabWidget->addTab(new frmWebServer, "WEB服务端");
#endif
#ifdef emsdk
AppConfig::CurrentIndex = 4;
#endif
}
void frmMain::initConfig()
{
ui->tabWidget->setCurrentIndex(AppConfig::CurrentIndex);
connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(saveConfig()));
}
void frmMain::saveConfig()
{
AppConfig::CurrentIndex = ui->tabWidget->currentIndex();
AppConfig::writeConfig();
}

View File

@@ -0,0 +1,27 @@
#ifndef FRMMAIN_H
#define FRMMAIN_H
#include <QWidget>
namespace Ui {
class frmMain;
}
class frmMain : public QWidget
{
Q_OBJECT
public:
explicit frmMain(QWidget *parent = 0);
~frmMain();
private:
Ui::frmMain *ui;
private slots:
void initForm();
void initConfig();
void saveConfig();
};
#endif // FRMMAIN_H

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmMain</class>
<widget class="QWidget" name="frmMain">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,282 @@
#include "frmtcpclient.h"
#include "ui_frmtcpclient.h"
#include "quihelper.h"
#include "quihelperdata.h"
frmTcpClient::frmTcpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpClient)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
}
frmTcpClient::~frmTcpClient()
{
delete ui;
}
bool frmTcpClient::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmTcpClient::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
isOk = false;
//实例化对象并绑定信号槽
socket = new QTcpSocket(this);
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(error()));
#else
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
#endif
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
AppData::loadIP(ui->cboxBindIP);
}
void frmTcpClient::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendTcpClient);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveTcpClient);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiTcpClient);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugTcpClient);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendTcpClient);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalTcpClient)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->cboxBindIP->setCurrentIndex(ui->cboxBindIP->findText(AppConfig::TcpBindIP));
connect(ui->cboxBindIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtBindPort->setText(QString::number(AppConfig::TcpBindPort));
connect(ui->txtBindPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->txtServerIP->setText(AppConfig::TcpServerIP);
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->txtServerPort->setText(QString::number(AppConfig::TcpServerPort));
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmTcpClient::saveConfig()
{
AppConfig::HexSendTcpClient = ui->ckHexSend->isChecked();
AppConfig::HexReceiveTcpClient = ui->ckHexReceive->isChecked();
AppConfig::AsciiTcpClient = ui->ckAscii->isChecked();
AppConfig::DebugTcpClient = ui->ckDebug->isChecked();
AppConfig::AutoSendTcpClient = ui->ckAutoSend->isChecked();
AppConfig::IntervalTcpClient = ui->cboxInterval->currentText().toInt();
AppConfig::TcpBindIP = ui->cboxBindIP->currentText();
AppConfig::TcpBindPort = ui->txtBindPort->text().trimmed().toInt();
AppConfig::TcpServerIP = ui->txtServerIP->text().trimmed();
AppConfig::TcpServerPort = ui->txtServerPort->text().trimmed().toInt();
AppConfig::writeConfig();
this->initTimer();
}
void frmTcpClient::initTimer()
{
if (timer->interval() != AppConfig::IntervalTcpClient) {
timer->setInterval(AppConfig::IntervalTcpClient);
}
if (AppConfig::AutoSendTcpClient) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmTcpClient::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmTcpClient::connected()
{
isOk = true;
ui->btnConnect->setText("断开");
append(0, "服务器连接");
append(0, QString("本地地址: %1 本地端口: %2").arg(socket->localAddress().toString()).arg(socket->localPort()));
append(0, QString("远程地址: %1 远程端口: %2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
}
void frmTcpClient::disconnected()
{
isOk = false;
ui->btnConnect->setText("连接");
append(1, "服务器断开");
}
void frmTcpClient::error()
{
append(2, socket->errorString());
}
void frmTcpClient::readData()
{
QByteArray data = socket->readAll();
if (data.length() <= 0) {
return;
}
QString buffer;
if (AppConfig::HexReceiveTcpClient) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else if (AppConfig::AsciiTcpClient) {
buffer = QUIHelperData::byteArrayToAsciiStr(data);
} else {
buffer = QString(data);
}
append(1, buffer);
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
if (AppConfig::DebugTcpClient) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(AppData::Values.at(i));
break;
}
}
}
}
void frmTcpClient::sendData(const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendTcpClient) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else if (AppConfig::AsciiTcpClient) {
buffer = QUIHelperData::asciiStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
socket->write(buffer);
append(0, data);
}
void frmTcpClient::on_btnConnect_clicked()
{
if (ui->btnConnect->text() == "连接") {
//断开所有连接和操作
//socket->abort();
//绑定网卡和端口
//有个后遗症,客户端这边断开连接后还会保持几分钟导致不能重复绑定
//如果是服务器断开则可以继续使用
//提示 The bound address is already in use
//参考 https://www.cnblogs.com/baiduboy/p/7426822.html
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
//socket->bind(QHostAddress(AppConfig::TcpBindIP), AppConfig::TcpBindPort);
#endif
//连接服务器
socket->connectToHost(AppConfig::TcpServerIP, AppConfig::TcpServerPort);
} else {
socket->abort();
}
}
void frmTcpClient::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmTcpClient::on_btnClear_clicked()
{
append(0, "", true);
}
void frmTcpClient::on_btnSend_clicked()
{
if (!isOk) {
return;
}
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
sendData(data);
}

View File

@@ -0,0 +1,50 @@
#ifndef FRMTCPCLIENT_H
#define FRMTCPCLIENT_H
#include <QWidget>
#include <QtNetwork>
namespace Ui {
class frmTcpClient;
}
class frmTcpClient : public QWidget
{
Q_OBJECT
public:
explicit frmTcpClient(QWidget *parent = 0);
~frmTcpClient();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmTcpClient *ui;
bool isOk;
QTcpSocket *socket;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void connected();
void disconnected();
void error();
void readData();
void sendData(const QString &data);
private slots:
void on_btnConnect_clicked();
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
};
#endif // FRMTCPCLIENT_H

View File

@@ -0,0 +1,264 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmTcpClient</class>
<widget class="QWidget" name="frmTcpClient">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>控制字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labBindIP">
<property name="text">
<string>绑定地址</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxBindIP"/>
</item>
<item>
<widget class="QLabel" name="labBindPort">
<property name="text">
<string>绑定端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtBindPort"/>
</item>
<item>
<widget class="QLabel" name="labServerIP">
<property name="text">
<string>服务器地址</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerIP"/>
</item>
<item>
<widget class="QLabel" name="labServerPort">
<property name="text">
<string>服务器端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerPort"/>
</item>
<item>
<widget class="QPushButton" name="btnConnect">
<property name="text">
<string>连接</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layTcpClient">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtMain</tabstop>
<tabstop>cboxData</tabstop>
<tabstop>btnSend</tabstop>
<tabstop>ckHexReceive</tabstop>
<tabstop>ckHexSend</tabstop>
<tabstop>ckAscii</tabstop>
<tabstop>ckShow</tabstop>
<tabstop>ckDebug</tabstop>
<tabstop>ckAutoSend</tabstop>
<tabstop>cboxInterval</tabstop>
<tabstop>cboxBindIP</tabstop>
<tabstop>txtBindPort</tabstop>
<tabstop>txtServerIP</tabstop>
<tabstop>txtServerPort</tabstop>
<tabstop>btnConnect</tabstop>
<tabstop>btnSave</tabstop>
<tabstop>btnClear</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,270 @@
#include "frmtcpserver.h"
#include "ui_frmtcpserver.h"
#include "quihelper.h"
frmTcpServer::frmTcpServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmTcpServer)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
on_btnListen_clicked();
}
frmTcpServer::~frmTcpServer()
{
//结束的时候停止服务
server->stop();
delete ui;
}
bool frmTcpServer::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmTcpServer::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
isOk = false;
//实例化对象并绑定信号槽
server = new TcpServer(this);
connect(server, SIGNAL(connected(QString, int)), this, SLOT(connected(QString, int)));
connect(server, SIGNAL(disconnected(QString, int)), this, SLOT(disconnected(QString, int)));
connect(server, SIGNAL(error(QString, int, QString)), this, SLOT(error(QString, int, QString)));
connect(server, SIGNAL(sendData(QString, int, QString)), this, SLOT(sendData(QString, int, QString)));
connect(server, SIGNAL(receiveData(QString, int, QString)), this, SLOT(receiveData(QString, int, QString)));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
AppData::loadIP(ui->cboxListenIP);
}
void frmTcpServer::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendTcpServer);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveTcpServer);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiTcpServer);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugTcpServer);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendTcpServer);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalTcpServer)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->cboxListenIP->setCurrentIndex(ui->cboxListenIP->findText(AppConfig::TcpListenIP));
connect(ui->cboxListenIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtListenPort->setText(QString::number(AppConfig::TcpListenPort));
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->ckSelectAll->setChecked(AppConfig::SelectAllTcpServer);
connect(ui->ckSelectAll, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmTcpServer::saveConfig()
{
AppConfig::HexSendTcpServer = ui->ckHexSend->isChecked();
AppConfig::HexReceiveTcpServer = ui->ckHexReceive->isChecked();
AppConfig::AsciiTcpServer = ui->ckAscii->isChecked();
AppConfig::DebugTcpServer = ui->ckDebug->isChecked();
AppConfig::AutoSendTcpServer = ui->ckAutoSend->isChecked();
AppConfig::IntervalTcpServer = ui->cboxInterval->currentText().toInt();
AppConfig::TcpListenIP = ui->cboxListenIP->currentText();
AppConfig::TcpListenPort = ui->txtListenPort->text().trimmed().toInt();
AppConfig::SelectAllTcpServer = ui->ckSelectAll->isChecked();
AppConfig::writeConfig();
this->initTimer();
}
void frmTcpServer::initTimer()
{
if (timer->interval() != AppConfig::IntervalTcpServer) {
timer->setInterval(AppConfig::IntervalTcpServer);
}
if (AppConfig::AutoSendTcpServer) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmTcpServer::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmTcpServer::connected(const QString &ip, int port)
{
append(0, QString("[%1:%2] %3").arg(ip).arg(port).arg("客户端上线"));
QString str = QString("%1:%2").arg(ip).arg(port);
ui->listWidget->addItem(str);
ui->labCount->setText(QString("共 %1 个客户端").arg(ui->listWidget->count()));
}
void frmTcpServer::disconnected(const QString &ip, int port)
{
append(2, QString("[%1:%2] %3").arg(ip).arg(port).arg("客户端下线"));
int row = -1;
QString str = QString("%1:%2").arg(ip).arg(port);
for (int i = 0; i < ui->listWidget->count(); i++) {
if (ui->listWidget->item(i)->text() == str) {
row = i;
break;
}
}
delete ui->listWidget->takeItem(row);
ui->labCount->setText(QString("共 %1 个客户端").arg(ui->listWidget->count()));
}
void frmTcpServer::error(const QString &ip, int port, const QString &error)
{
append(2, QString("[%1:%2] %3").arg(ip).arg(port).arg(error));
}
void frmTcpServer::sendData(const QString &ip, int port, const QString &data)
{
append(0, QString("[%1:%2] %3").arg(ip).arg(port).arg(data));
}
void frmTcpServer::receiveData(const QString &ip, int port, const QString &data)
{
append(1, QString("[%1:%2] %3").arg(ip).arg(port).arg(data));
}
void frmTcpServer::on_btnListen_clicked()
{
if (ui->btnListen->text() == "监听") {
isOk = server->start();
if (isOk) {
append(0, "监听成功");
ui->btnListen->setText("关闭");
}
} else {
isOk = false;
server->stop();
ui->btnListen->setText("监听");
}
}
void frmTcpServer::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmTcpServer::on_btnClear_clicked()
{
append(0, "", true);
}
void frmTcpServer::on_btnSend_clicked()
{
if (!isOk) {
return;
}
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
if (ui->ckSelectAll->isChecked()) {
server->writeData(data);
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
QString str = ui->listWidget->item(row)->text();
QStringList list = str.split(":");
server->writeData(list.at(0), list.at(1).toInt(), data);
}
}
}
void frmTcpServer::on_btnRemove_clicked()
{
if (ui->ckSelectAll->isChecked()) {
server->remove();
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
QString str = ui->listWidget->item(row)->text();
QStringList list = str.split(":");
server->remove(list.at(0), list.at(1).toInt());
}
}
}

View File

@@ -0,0 +1,52 @@
#ifndef FRMTCPSERVER_H
#define FRMTCPSERVER_H
#include <QWidget>
#include "tcpserver.h"
namespace Ui {
class frmTcpServer;
}
class frmTcpServer : public QWidget
{
Q_OBJECT
public:
explicit frmTcpServer(QWidget *parent = 0);
~frmTcpServer();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmTcpServer *ui;
bool isOk;
TcpServer *server;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void connected(const QString &ip, int port);
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
private slots:
void on_btnListen_clicked();
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
void on_btnRemove_clicked();
};
#endif // FRMTCPSERVER_H

View File

@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmTcpServer</class>
<widget class="QWidget" name="frmTcpServer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>控制字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labListenIP">
<property name="text">
<string>监听地址</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxListenIP"/>
</item>
<item>
<widget class="QLabel" name="labListenPort">
<property name="text">
<string>监听端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtListenPort"/>
</item>
<item>
<widget class="QPushButton" name="btnListen">
<property name="text">
<string>监听</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemove">
<property name="text">
<string>移除</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labCount">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string>共 0 个客户端</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QCheckBox" name="ckSelectAll">
<property name="text">
<string>对所有客户端发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layTcpServer">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtMain</tabstop>
<tabstop>cboxData</tabstop>
<tabstop>btnSend</tabstop>
<tabstop>ckHexReceive</tabstop>
<tabstop>ckHexSend</tabstop>
<tabstop>ckAscii</tabstop>
<tabstop>ckShow</tabstop>
<tabstop>ckDebug</tabstop>
<tabstop>ckAutoSend</tabstop>
<tabstop>cboxInterval</tabstop>
<tabstop>cboxListenIP</tabstop>
<tabstop>txtListenPort</tabstop>
<tabstop>btnListen</tabstop>
<tabstop>btnSave</tabstop>
<tabstop>btnClear</tabstop>
<tabstop>btnRemove</tabstop>
<tabstop>listWidget</tabstop>
<tabstop>ckSelectAll</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,258 @@
#include "frmudpclient.h"
#include "ui_frmudpclient.h"
#include "quihelper.h"
#include "quihelperdata.h"
frmUdpClient::frmUdpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmUdpClient)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
}
frmUdpClient::~frmUdpClient()
{
delete ui;
}
bool frmUdpClient::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmUdpClient::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
//实例化对象并绑定信号槽
socket = new QUdpSocket(this);
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(error()));
#else
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
#endif
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
AppData::loadIP(ui->cboxBindIP);
}
void frmUdpClient::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendUdpClient);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveUdpClient);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiUdpClient);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugUdpClient);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendUdpClient);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalUdpClient)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->cboxBindIP->setCurrentIndex(ui->cboxBindIP->findText(AppConfig::UdpBindIP));
connect(ui->cboxBindIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtBindPort->setText(QString::number(AppConfig::UdpBindPort));
connect(ui->txtBindPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->txtServerIP->setText(AppConfig::UdpServerIP);
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->txtServerPort->setText(QString::number(AppConfig::UdpServerPort));
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmUdpClient::saveConfig()
{
AppConfig::HexSendUdpClient = ui->ckHexSend->isChecked();
AppConfig::HexReceiveUdpClient = ui->ckHexReceive->isChecked();
AppConfig::AsciiUdpClient = ui->ckAscii->isChecked();
AppConfig::DebugUdpClient = ui->ckDebug->isChecked();
AppConfig::AutoSendUdpClient = ui->ckAutoSend->isChecked();
AppConfig::IntervalUdpClient = ui->cboxInterval->currentText().toInt();
AppConfig::UdpBindIP = ui->cboxBindIP->currentText();
AppConfig::UdpBindPort = ui->txtBindPort->text().trimmed().toInt();
AppConfig::UdpServerIP = ui->txtServerIP->text().trimmed();
AppConfig::UdpServerPort = ui->txtServerPort->text().trimmed().toInt();
AppConfig::writeConfig();
this->initTimer();
}
void frmUdpClient::initTimer()
{
if (timer->interval() != AppConfig::IntervalUdpClient) {
timer->setInterval(AppConfig::IntervalUdpClient);
}
if (AppConfig::AutoSendUdpClient) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmUdpClient::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmUdpClient::error()
{
append(2, socket->errorString());
}
void frmUdpClient::readData()
{
QHostAddress host;
quint16 port;
QByteArray data;
QString buffer;
while (socket->hasPendingDatagrams()) {
data.resize(socket->pendingDatagramSize());
socket->readDatagram(data.data(), data.size(), &host, &port);
if (AppConfig::HexReceiveUdpClient) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else if (AppConfig::AsciiUdpClient) {
buffer = QUIHelperData::byteArrayToAsciiStr(data);
} else {
buffer = QString(data);
}
QString ip = host.toString();
ip = ip.replace("::ffff:", "");
if (ip.isEmpty()) {
continue;
}
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(buffer);
append(1, str);
if (AppConfig::DebugUdpClient) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(ip, port, AppData::Values.at(i));
break;
}
}
}
}
}
void frmUdpClient::sendData(const QString &ip, int port, const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendUdpClient) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else if (AppConfig::AsciiUdpClient) {
buffer = QUIHelperData::asciiStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
//绑定网卡和端口,没有绑定过才需要绑定
//采用端口是否一样来判断是为了方便可以直接动态绑定切换端口
if (socket->localPort() != AppConfig::UdpBindPort) {
socket->abort();
socket->bind(QHostAddress(AppConfig::UdpBindIP), AppConfig::UdpBindPort);
}
//指定地址和端口发送数据
socket->writeDatagram(buffer, QHostAddress(ip), port);
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
append(0, str);
}
void frmUdpClient::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmUdpClient::on_btnClear_clicked()
{
append(0, "", true);
}
void frmUdpClient::on_btnSend_clicked()
{
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
sendData(AppConfig::UdpServerIP, AppConfig::UdpServerPort, data);
}

View File

@@ -0,0 +1,46 @@
#ifndef FRMUDPCLIENT_H
#define FRMUDPCLIENT_H
#include <QWidget>
#include <QtNetwork>
namespace Ui {
class frmUdpClient;
}
class frmUdpClient : public QWidget
{
Q_OBJECT
public:
explicit frmUdpClient(QWidget *parent = 0);
~frmUdpClient();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmUdpClient *ui;
QUdpSocket *socket;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void error();
void readData();
void sendData(const QString &ip, int port, const QString &data);
private slots:
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
};
#endif // FRMUDPCLIENT_H

View File

@@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmUdpClient</class>
<widget class="QWidget" name="frmUdpClient">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>控制字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labBindIP">
<property name="text">
<string>绑定地址</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxBindIP"/>
</item>
<item>
<widget class="QLabel" name="labBindPort">
<property name="text">
<string>绑定端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtBindPort"/>
</item>
<item>
<widget class="QLabel" name="labServerIP">
<property name="text">
<string>服务器地址</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerIP"/>
</item>
<item>
<widget class="QLabel" name="labServerPort">
<property name="text">
<string>服务器端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerPort"/>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layUdpServer">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtMain</tabstop>
<tabstop>cboxData</tabstop>
<tabstop>btnSend</tabstop>
<tabstop>ckHexReceive</tabstop>
<tabstop>ckHexSend</tabstop>
<tabstop>ckAscii</tabstop>
<tabstop>ckShow</tabstop>
<tabstop>ckDebug</tabstop>
<tabstop>ckAutoSend</tabstop>
<tabstop>cboxInterval</tabstop>
<tabstop>cboxBindIP</tabstop>
<tabstop>txtBindPort</tabstop>
<tabstop>txtServerIP</tabstop>
<tabstop>txtServerPort</tabstop>
<tabstop>btnSave</tabstop>
<tabstop>btnClear</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,299 @@
#include "frmudpserver.h"
#include "ui_frmudpserver.h"
#include "quihelper.h"
#include "quihelperdata.h"
frmUdpServer::frmUdpServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmUdpServer)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
on_btnListen_clicked();
}
frmUdpServer::~frmUdpServer()
{
delete ui;
}
bool frmUdpServer::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmUdpServer::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
//实例化对象并绑定信号槽
socket = new QUdpSocket(this);
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
connect(socket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(error()));
#else
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
#endif
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
AppData::loadIP(ui->cboxListenIP);
}
void frmUdpServer::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendUdpServer);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveUdpServer);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiUdpServer);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugUdpServer);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendUdpServer);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalUdpServer)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->cboxListenIP->setCurrentIndex(ui->cboxListenIP->findText(AppConfig::UdpListenIP));
connect(ui->cboxListenIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtListenPort->setText(QString::number(AppConfig::UdpListenPort));
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->ckSelectAll->setChecked(AppConfig::SelectAllUdpServer);
connect(ui->ckSelectAll, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmUdpServer::saveConfig()
{
AppConfig::HexSendUdpServer = ui->ckHexSend->isChecked();
AppConfig::HexReceiveUdpServer = ui->ckHexReceive->isChecked();
AppConfig::AsciiUdpServer = ui->ckAscii->isChecked();
AppConfig::DebugUdpServer = ui->ckDebug->isChecked();
AppConfig::AutoSendUdpServer = ui->ckAutoSend->isChecked();
AppConfig::IntervalUdpServer = ui->cboxInterval->currentText().toInt();
AppConfig::UdpListenIP = ui->cboxListenIP->currentText();
AppConfig::UdpListenPort = ui->txtListenPort->text().trimmed().toInt();
AppConfig::SelectAllUdpServer = ui->ckSelectAll->isChecked();
AppConfig::writeConfig();
this->initTimer();
}
void frmUdpServer::initTimer()
{
if (timer->interval() != AppConfig::IntervalUdpServer) {
timer->setInterval(AppConfig::IntervalUdpServer);
}
if (AppConfig::AutoSendUdpServer) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmUdpServer::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmUdpServer::error()
{
append(2, socket->errorString());
}
void frmUdpServer::readData()
{
QHostAddress host;
quint16 port;
QByteArray data;
QString buffer;
while (socket->hasPendingDatagrams()) {
data.resize(socket->pendingDatagramSize());
socket->readDatagram(data.data(), data.size(), &host, &port);
if (AppConfig::HexReceiveUdpServer) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else if (AppConfig::AsciiUdpServer) {
buffer = QUIHelperData::byteArrayToAsciiStr(data);
} else {
buffer = QString(data);
}
QString ip = host.toString();
ip = ip.replace("::ffff:", "");
if (ip.isEmpty()) {
continue;
}
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(buffer);
append(1, str);
//先过滤重复的
str = QString("%1:%2").arg(ip).arg(port);
for (int i = 0; i < ui->listWidget->count(); i++) {
QString s = ui->listWidget->item(i)->text();
if (str == s) {
return;
}
}
//添加到列表
ui->listWidget->addItem(str);
ui->labCount->setText(QString("共 %1 个客户端").arg(ui->listWidget->count()));
if (AppConfig::DebugUdpServer) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(ip, port, AppData::Values.at(i));
break;
}
}
}
}
}
void frmUdpServer::sendData(const QString &ip, int port, const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendUdpServer) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else if (AppConfig::AsciiUdpServer) {
buffer = QUIHelperData::asciiStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
socket->writeDatagram(buffer, QHostAddress(ip), port);
QString str = QString("[%1:%2] %3").arg(ip).arg(port).arg(data);
append(0, str);
}
void frmUdpServer::on_btnListen_clicked()
{
if (ui->btnListen->text() == "监听") {
bool ok = socket->bind(QHostAddress(AppConfig::UdpListenIP), AppConfig::UdpListenPort);
if (ok) {
ui->btnListen->setText("关闭");
append(0, "监听成功");
}
} else {
socket->abort();
ui->btnListen->setText("监听");
}
}
void frmUdpServer::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmUdpServer::on_btnClear_clicked()
{
append(0, "", true);
}
void frmUdpServer::on_btnSend_clicked()
{
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
if (ui->ckSelectAll->isChecked()) {
for (int i = 0; i < ui->listWidget->count(); i++) {
QString str = ui->listWidget->item(i)->text();
QStringList list = str.split(":");
sendData(list.at(0), list.at(1).toInt(), data);
}
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
QString str = ui->listWidget->item(row)->text();
QStringList list = str.split(":");
sendData(list.at(0), list.at(1).toInt(), data);
}
}
}
void frmUdpServer::on_btnRemove_clicked()
{
if (ui->ckSelectAll->isChecked()) {
ui->listWidget->clear();
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
delete ui->listWidget->takeItem(row);
}
}
}

View File

@@ -0,0 +1,48 @@
#ifndef FRMUDPSERVER_H
#define FRMUDPSERVER_H
#include <QWidget>
#include <QtNetwork>
namespace Ui {
class frmUdpServer;
}
class frmUdpServer : public QWidget
{
Q_OBJECT
public:
explicit frmUdpServer(QWidget *parent = 0);
~frmUdpServer();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmUdpServer *ui;
QUdpSocket *socket;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void error();
void readData();
void sendData(const QString &ip, int port, const QString &data);
private slots:
void on_btnListen_clicked();
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
void on_btnRemove_clicked();
};
#endif // FRMUDPSERVER_H

View File

@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmUdpServer</class>
<widget class="QWidget" name="frmUdpServer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>控制字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labListenIP">
<property name="text">
<string>监听地址</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxListenIP"/>
</item>
<item>
<widget class="QLabel" name="labListenPort">
<property name="text">
<string>监听端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtListenPort"/>
</item>
<item>
<widget class="QPushButton" name="btnListen">
<property name="text">
<string>监听</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemove">
<property name="text">
<string>移除</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labCount">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string>共 0 个客户端</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QCheckBox" name="ckSelectAll">
<property name="text">
<string>对所有客户端发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layUdpServer">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtMain</tabstop>
<tabstop>cboxData</tabstop>
<tabstop>btnSend</tabstop>
<tabstop>ckHexReceive</tabstop>
<tabstop>ckHexSend</tabstop>
<tabstop>ckAscii</tabstop>
<tabstop>ckShow</tabstop>
<tabstop>ckDebug</tabstop>
<tabstop>ckAutoSend</tabstop>
<tabstop>cboxInterval</tabstop>
<tabstop>cboxListenIP</tabstop>
<tabstop>txtListenPort</tabstop>
<tabstop>btnListen</tabstop>
<tabstop>btnSave</tabstop>
<tabstop>btnClear</tabstop>
<tabstop>listWidget</tabstop>
<tabstop>ckSelectAll</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,278 @@
#include "frmwebclient.h"
#include "ui_frmwebclient.h"
#include "quihelper.h"
#include "quihelperdata.h"
frmWebClient::frmWebClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmWebClient)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
}
frmWebClient::~frmWebClient()
{
delete ui;
}
bool frmWebClient::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmWebClient::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
isOk = false;
//实例化对象并绑定信号槽
socket = new QWebSocket("WebSocket", QWebSocketProtocol::VersionLatest, this);
connect(socket, SIGNAL(connected()), this, SLOT(connected()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error()));
//暂时使用前面两个信号,部分系统上后面两个信号Qt没实现,目前测试到5.15.2
//在win上如果两组信号都关联了则都会触发,另外一组信号就是多个参数表示是否是最后一个数据包
connect(socket, SIGNAL(textMessageReceived(QString)), this, SLOT(textMessageReceived(QString)));
connect(socket, SIGNAL(binaryMessageReceived(QByteArray)), this, SLOT(binaryMessageReceived(QByteArray)));
//connect(socket, SIGNAL(textFrameReceived(QString, bool)), this, SLOT(textFrameReceived(QString, bool)));
//connect(socket, SIGNAL(binaryFrameReceived(QByteArray, bool)), this, SLOT(binaryFrameReceived(QByteArray, bool)));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
}
void frmWebClient::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendWebClient);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveWebClient);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiWebClient);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugWebClient);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendWebClient);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalWebClient)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtServerIP->setText(AppConfig::WebServerIP);
connect(ui->txtServerIP, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->txtServerPort->setText(QString::number(AppConfig::WebServerPort));
connect(ui->txtServerPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmWebClient::saveConfig()
{
AppConfig::HexSendWebClient = ui->ckHexSend->isChecked();
AppConfig::HexReceiveWebClient = ui->ckHexReceive->isChecked();
AppConfig::AsciiWebClient = ui->ckAscii->isChecked();
AppConfig::DebugWebClient = ui->ckDebug->isChecked();
AppConfig::AutoSendWebClient = ui->ckAutoSend->isChecked();
AppConfig::IntervalWebClient = ui->cboxInterval->currentText().toInt();
AppConfig::WebServerIP = ui->txtServerIP->text().trimmed();
AppConfig::WebServerPort = ui->txtServerPort->text().trimmed().toInt();
AppConfig::writeConfig();
this->initTimer();
}
void frmWebClient::initTimer()
{
if (timer->interval() != AppConfig::IntervalWebClient) {
timer->setInterval(AppConfig::IntervalWebClient);
}
if (AppConfig::AutoSendWebClient) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmWebClient::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmWebClient::connected()
{
isOk = true;
ui->btnConnect->setText("断开");
append(0, "服务器连接");
append(0, QString("本地地址: %1 本地端口: %2").arg(socket->localAddress().toString()).arg(socket->localPort()));
append(0, QString("远程地址: %1 远程端口: %2").arg(socket->peerAddress().toString()).arg(socket->peerPort()));
}
void frmWebClient::disconnected()
{
isOk = false;
ui->btnConnect->setText("连接");
append(1, "服务器断开");
}
void frmWebClient::error()
{
append(2, socket->errorString());
}
void frmWebClient::sendData(const QString &data)
{
QByteArray buffer;
if (AppConfig::HexSendWebClient) {
buffer = QUIHelperData::hexStrToByteArray(data);
} else {
buffer = data.toUtf8();
}
if (AppConfig::AsciiWebClient) {
socket->sendTextMessage(data);
} else {
socket->sendBinaryMessage(buffer);
}
append(0, data);
}
void frmWebClient::textFrameReceived(const QString &data, bool isLastFrame)
{
QString buffer = data;
append(1, buffer);
//自动回复数据,可以回复的数据是以;隔开,每行可以带多个;所以这里不需要继续判断
if (AppConfig::DebugWebClient) {
int count = AppData::Keys.count();
for (int i = 0; i < count; i++) {
if (AppData::Keys.at(i) == buffer) {
sendData(AppData::Values.at(i));
break;
}
}
}
}
void frmWebClient::binaryFrameReceived(const QByteArray &data, bool isLastFrame)
{
QString buffer;
if (AppConfig::HexReceiveWebClient) {
buffer = QUIHelperData::byteArrayToHexStr(data);
} else {
buffer = QString(data);
}
textFrameReceived(buffer, isLastFrame);
}
void frmWebClient::textMessageReceived(const QString &data)
{
textFrameReceived(data, true);
}
void frmWebClient::binaryMessageReceived(const QByteArray &data)
{
binaryFrameReceived(data, true);
}
void frmWebClient::on_btnConnect_clicked()
{
if (ui->btnConnect->text() == "连接") {
QString url = QString("%1:%2").arg(AppConfig::WebServerIP).arg(AppConfig::WebServerPort);
socket->abort();
socket->open(QUrl(url));
} else {
socket->abort();
}
}
void frmWebClient::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmWebClient::on_btnClear_clicked()
{
append(0, "", true);
}
void frmWebClient::on_btnSend_clicked()
{
if (!isOk) {
return;
}
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
sendData(data);
}

View File

@@ -0,0 +1,54 @@
#ifndef FRMWEBCLIENT_H
#define FRMWEBCLIENT_H
#include <QWidget>
#include <QtWebSockets>
namespace Ui {
class frmWebClient;
}
class frmWebClient : public QWidget
{
Q_OBJECT
public:
explicit frmWebClient(QWidget *parent = 0);
~frmWebClient();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmWebClient *ui;
bool isOk;
QWebSocket *socket;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void connected();
void disconnected();
void error();
void sendData(const QString &data);
void textFrameReceived(const QString &data, bool isLastFrame);
void binaryFrameReceived(const QByteArray &data, bool isLastFrame);
void textMessageReceived(const QString &data);
void binaryMessageReceived(const QByteArray &data);
private slots:
void on_btnConnect_clicked();
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
};
#endif // FRMWEBCLIENT_H

View File

@@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmWebClient</class>
<widget class="QWidget" name="frmWebClient">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>文本字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labServerIP">
<property name="text">
<string>服务器地址</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerIP"/>
</item>
<item>
<widget class="QLabel" name="labServerPort">
<property name="text">
<string>服务器端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtServerPort"/>
</item>
<item>
<widget class="QPushButton" name="btnConnect">
<property name="text">
<string>连接</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layTcpClient">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,268 @@
#include "frmwebserver.h"
#include "ui_frmwebserver.h"
#include "quihelper.h"
frmWebServer::frmWebServer(QWidget *parent) : QWidget(parent), ui(new Ui::frmWebServer)
{
ui->setupUi(this);
this->initForm();
this->initConfig();
on_btnListen_clicked();
}
frmWebServer::~frmWebServer()
{
delete ui;
}
bool frmWebServer::eventFilter(QObject *watched, QEvent *event)
{
//双击清空
if (watched == ui->txtMain->viewport()) {
if (event->type() == QEvent::MouseButtonDblClick) {
on_btnClear_clicked();
}
}
return QWidget::eventFilter(watched, event);
}
void frmWebServer::initForm()
{
QFont font;
font.setPixelSize(16);
ui->txtMain->setFont(font);
ui->txtMain->viewport()->installEventFilter(this);
isOk = false;
//实例化对象并绑定信号槽
server = new WebServer("WebServer", QWebSocketServer::NonSecureMode, this);
connect(server, SIGNAL(connected(QString, int)), this, SLOT(connected(QString, int)));
connect(server, SIGNAL(disconnected(QString, int)), this, SLOT(disconnected(QString, int)));
connect(server, SIGNAL(error(QString, int, QString)), this, SLOT(error(QString, int, QString)));
connect(server, SIGNAL(sendData(QString, int, QString)), this, SLOT(sendData(QString, int, QString)));
connect(server, SIGNAL(receiveData(QString, int, QString)), this, SLOT(receiveData(QString, int, QString)));
//定时器发送数据
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(on_btnSend_clicked()));
//填充数据到下拉框
ui->cboxInterval->addItems(AppData::Intervals);
ui->cboxData->addItems(AppData::Datas);
AppData::loadIP(ui->cboxListenIP);
}
void frmWebServer::initConfig()
{
ui->ckHexSend->setChecked(AppConfig::HexSendWebServer);
connect(ui->ckHexSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckHexReceive->setChecked(AppConfig::HexReceiveWebServer);
connect(ui->ckHexReceive, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAscii->setChecked(AppConfig::AsciiWebServer);
connect(ui->ckAscii, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckDebug->setChecked(AppConfig::DebugWebServer);
connect(ui->ckDebug, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->ckAutoSend->setChecked(AppConfig::AutoSendWebServer);
connect(ui->ckAutoSend, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
ui->cboxInterval->setCurrentIndex(ui->cboxInterval->findText(QString::number(AppConfig::IntervalWebServer)));
connect(ui->cboxInterval, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->cboxListenIP->setCurrentIndex(ui->cboxListenIP->findText(AppConfig::WebListenIP));
connect(ui->cboxListenIP, SIGNAL(currentIndexChanged(int)), this, SLOT(saveConfig()));
ui->txtListenPort->setText(QString::number(AppConfig::WebListenPort));
connect(ui->txtListenPort, SIGNAL(textChanged(QString)), this, SLOT(saveConfig()));
ui->ckSelectAll->setChecked(AppConfig::SelectAllWebServer);
connect(ui->ckSelectAll, SIGNAL(stateChanged(int)), this, SLOT(saveConfig()));
this->initTimer();
}
void frmWebServer::saveConfig()
{
AppConfig::HexSendWebServer = ui->ckHexSend->isChecked();
AppConfig::HexReceiveWebServer = ui->ckHexReceive->isChecked();
AppConfig::AsciiWebServer = ui->ckAscii->isChecked();
AppConfig::DebugWebServer = ui->ckDebug->isChecked();
AppConfig::AutoSendWebServer = ui->ckAutoSend->isChecked();
AppConfig::IntervalWebServer = ui->cboxInterval->currentText().toInt();
AppConfig::WebListenIP = ui->cboxListenIP->currentText();
AppConfig::WebListenPort = ui->txtListenPort->text().trimmed().toInt();
AppConfig::SelectAllWebServer = ui->ckSelectAll->isChecked();
AppConfig::writeConfig();
this->initTimer();
}
void frmWebServer::initTimer()
{
if (timer->interval() != AppConfig::IntervalWebServer) {
timer->setInterval(AppConfig::IntervalWebServer);
}
if (AppConfig::AutoSendWebServer) {
if (!timer->isActive()) {
timer->start();
}
} else {
if (timer->isActive()) {
timer->stop();
}
}
}
void frmWebServer::append(int type, const QString &data, bool clear)
{
static int currentCount = 0;
static int maxCount = 100;
if (clear) {
ui->txtMain->clear();
currentCount = 0;
return;
}
if (currentCount >= maxCount) {
ui->txtMain->clear();
currentCount = 0;
}
if (ui->ckShow->isChecked()) {
return;
}
//过滤回车换行符
QString strData = data;
strData = strData.replace("\r", "");
strData = strData.replace("\n", "");
//不同类型不同颜色显示
QString strType;
if (type == 0) {
strType = "发送";
ui->txtMain->setTextColor(QColor("#22A3A9"));
} else if (type == 1) {
strType = "接收";
ui->txtMain->setTextColor(QColor("#753775"));
} else {
strType = "错误";
ui->txtMain->setTextColor(QColor("#D64D54"));
}
strData = QString("时间[%1] %2: %3").arg(TIMEMS).arg(strType).arg(strData);
ui->txtMain->append(strData);
currentCount++;
}
void frmWebServer::connected(const QString &ip, int port)
{
append(0, QString("[%1:%2] %3").arg(ip).arg(port).arg("客户端上线"));
QString str = QString("%1:%2").arg(ip).arg(port);
ui->listWidget->addItem(str);
ui->labCount->setText(QString("共 %1 个客户端").arg(ui->listWidget->count()));
}
void frmWebServer::disconnected(const QString &ip, int port)
{
append(2, QString("[%1:%2] %3").arg(ip).arg(port).arg("客户端下线"));
int row = -1;
QString str = QString("%1:%2").arg(ip).arg(port);
for (int i = 0; i < ui->listWidget->count(); i++) {
if (ui->listWidget->item(i)->text() == str) {
row = i;
break;
}
}
delete ui->listWidget->takeItem(row);
ui->labCount->setText(QString("共 %1 个客户端").arg(ui->listWidget->count()));
}
void frmWebServer::error(const QString &ip, int port, const QString &error)
{
append(2, QString("[%1:%2] %3").arg(ip).arg(port).arg(error));
}
void frmWebServer::sendData(const QString &ip, int port, const QString &data)
{
append(0, QString("[%1:%2] %3").arg(ip).arg(port).arg(data));
}
void frmWebServer::receiveData(const QString &ip, int port, const QString &data)
{
append(1, QString("[%1:%2] %3").arg(ip).arg(port).arg(data));
}
void frmWebServer::on_btnListen_clicked()
{
if (ui->btnListen->text() == "监听") {
isOk = server->start();
if (isOk) {
append(0, "监听成功");
ui->btnListen->setText("关闭");
}
} else {
isOk = false;
server->stop();
ui->btnListen->setText("监听");
}
}
void frmWebServer::on_btnSave_clicked()
{
QString data = ui->txtMain->toPlainText();
AppData::saveData(data);
on_btnClear_clicked();
}
void frmWebServer::on_btnClear_clicked()
{
append(0, "", true);
}
void frmWebServer::on_btnSend_clicked()
{
if (!isOk) {
return;
}
QString data = ui->cboxData->currentText();
if (data.length() <= 0) {
return;
}
if (ui->ckSelectAll->isChecked()) {
server->writeData(data);
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
QString str = ui->listWidget->item(row)->text();
QStringList list = str.split(":");
server->writeData(list.at(0), list.at(1).toInt(), data);
}
}
}
void frmWebServer::on_btnRemove_clicked()
{
if (ui->ckSelectAll->isChecked()) {
server->remove();
} else {
int row = ui->listWidget->currentRow();
if (row >= 0) {
QString str = ui->listWidget->item(row)->text();
QStringList list = str.split(":");
server->remove(list.at(0), list.at(1).toInt());
}
}
}

View File

@@ -0,0 +1,52 @@
#ifndef FRMWEBSERVER_H
#define FRMWEBSERVER_H
#include <QWidget>
#include "webserver.h"
namespace Ui {
class frmWebServer;
}
class frmWebServer : public QWidget
{
Q_OBJECT
public:
explicit frmWebServer(QWidget *parent = 0);
~frmWebServer();
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
Ui::frmWebServer *ui;
bool isOk;
WebServer *server;
QTimer *timer;
private slots:
void initForm();
void initConfig();
void saveConfig();
void initTimer();
void append(int type, const QString &data, bool clear = false);
private slots:
void connected(const QString &ip, int port);
void disconnected(const QString &ip, int port);
void error(const QString &ip, int port, const QString &error);
void sendData(const QString &ip, int port, const QString &data);
void receiveData(const QString &ip, int port, const QString &data);
private slots:
void on_btnListen_clicked();
void on_btnSave_clicked();
void on_btnClear_clicked();
void on_btnSend_clicked();
void on_btnRemove_clicked();
};
#endif // FRMWEBSERVER_H

View File

@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>frmWebServer</class>
<widget class="QWidget" name="frmWebServer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QTextEdit" name="txtMain">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<item>
<widget class="QCheckBox" name="ckHexReceive">
<property name="text">
<string>16进制接收</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckHexSend">
<property name="text">
<string>16进制发送</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAscii">
<property name="text">
<string>文本字符</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckShow">
<property name="text">
<string>暂停显示</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckDebug">
<property name="text">
<string>模拟设备</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ckAutoSend">
<property name="text">
<string>定时发送</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxInterval"/>
</item>
<item>
<widget class="QLabel" name="labListenIP">
<property name="text">
<string>监听地址</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cboxListenIP"/>
</item>
<item>
<widget class="QLabel" name="labListenPort">
<property name="text">
<string>监听端口</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtListenPort"/>
</item>
<item>
<widget class="QPushButton" name="btnListen">
<property name="text">
<string>监听</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSave">
<property name="text">
<string>保存</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnClear">
<property name="text">
<string>清空</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnRemove">
<property name="text">
<string>移除</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labCount">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string>共 0 个客户端</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidget"/>
</item>
<item>
<widget class="QCheckBox" name="ckSelectAll">
<property name="text">
<string>对所有客户端发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="layTcpServer">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="cboxData">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnSend">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>发送</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>txtMain</tabstop>
<tabstop>cboxData</tabstop>
<tabstop>btnSend</tabstop>
<tabstop>ckHexReceive</tabstop>
<tabstop>ckHexSend</tabstop>
<tabstop>ckAscii</tabstop>
<tabstop>ckShow</tabstop>
<tabstop>ckDebug</tabstop>
<tabstop>ckAutoSend</tabstop>
<tabstop>cboxInterval</tabstop>
<tabstop>cboxListenIP</tabstop>
<tabstop>txtListenPort</tabstop>
<tabstop>btnListen</tabstop>
<tabstop>btnSave</tabstop>
<tabstop>btnClear</tabstop>
<tabstop>btnRemove</tabstop>
<tabstop>listWidget</tabstop>
<tabstop>ckSelectAll</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

21
tool/nettool/head.h Normal file
View File

@@ -0,0 +1,21 @@
#include <QtCore>
#include <QtGui>
#include <QtNetwork>
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#ifdef websocket
#include <QtWebSockets>
#endif
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QtCore5Compat>
#endif
#pragma execution_character_set("utf-8")
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
#define STRDATETIME qPrintable(QDateTime::currentDateTime().toString("yyyy-MM-dd-HH-mm-ss"))
#include "appconfig.h"
#include "appdata.h"

27
tool/nettool/main.cpp Normal file
View File

@@ -0,0 +1,27 @@
#include "frmmain.h"
#include "quihelper.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/main.ico"));
//设置编码+字体+中文翻译文件
QUIHelper::initAll();
//读取配置文件
AppConfig::ConfigFile = QString("%1/%2.ini").arg(QUIHelper::appPath()).arg(QUIHelper::appName());
AppConfig::readConfig();
AppData::Intervals << "1" << "10" << "20" << "50" << "100" << "200" << "300" << "500" << "1000" << "1500" << "2000" << "3000" << "5000" << "10000";
AppData::readSendData();
AppData::readDeviceData();
frmMain w;
w.setWindowTitle("网络调试助手 V2022 (QQ: 517216493 WX: feiyangqingyun)");
w.resize(950, 700);
QUIHelper::setFormInCenter(&w);
w.show();
return a.exec();
}

32
tool/nettool/nettool.pro Normal file
View File

@@ -0,0 +1,32 @@
QT += core gui network
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
#判断是否有websocket模块
qtHaveModule(websockets) {
QT += websockets
DEFINES += websocket
}}
greaterThan(QT_MAJOR_VERSION, 5): QT += core5compat
TARGET = nettool
TEMPLATE = app
RC_FILE = qrc/main.rc
wasm {
DEFINES += emsdk
RESOURCES += qrc/font.qrc
} else {
DESTDIR = $$PWD/../bin
}
HEADERS += head.h
SOURCES += main.cpp
RESOURCES += qrc/main.qrc
CONFIG += warn_off
INCLUDEPATH += $$PWD
INCLUDEPATH += $$PWD/api
INCLUDEPATH += $$PWD/form
include ($$PWD/api/api.pri)
include ($$PWD/form/form.pri)

Binary file not shown.

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>DroidSansFallback.ttf</file>
</qresource>
</RCC>

BIN
tool/nettool/qrc/main.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>main.ico</file>
<file>qm/qt_zh_CN.qm</file>
<file>qm/widgets.qm</file>
</qresource>
</RCC>

1
tool/nettool/qrc/main.rc Normal file
View File

@@ -0,0 +1 @@
IDI_ICON1 ICON DISCARDABLE "main.ico"

Binary file not shown.

Binary file not shown.

14
tool/nettool/readme.md Normal file
View File

@@ -0,0 +1,14 @@
**基本功能**
1. 16进制数据和ASCII数据收发。
2. 定时器自动发送。
3. 自动从配置文件加载最后一次的界面设置。
4. 自动从配置文件加载数据发送下拉框的数据。可以将经常使用的数据填写在send.txt中。
5. 可启用设备模拟回复当收到某个数据时模拟设备自动回复数据。对应数据格式填写在device.txt中。
6. 可对单个在线连接发送数据,也可勾选全部进行发送。
7. 支持多个客户端连接并发。
8. 采用单线程。
9. 多种模式tcp客户端、tcp服务器、udp客户端、udp服务器、websocket客户端、websocket服务器。
**其他说明**
1. 编译后请将源码下的file目录中的所有文件复制到可执行文件同一目录。
2. 如果有更好的建议或者意见,请留言,谢谢!