C++基于开源Modbus Tcp 通讯应用客户端(稳定高效,多线程后台状态读取,不卡顿)

2023-11-03

C++基于开源Modbus Tcp 通讯应用客户端


前言

使用多线程后台批量刷寄存器的状态,在某种程度上保证了上层接口读取的时候,不会卡顿,
整体应用效果比较友好。程序应用简单稳定高效,是一个比较不错的尝试。


一、演示效果

请添加图片描述

二、关键程序

1.头文件

代码如下:

#pragma once
#include "modbustcpclient_global.h"
#include <QObject>
#include <QThread>
#include <QHash>
#include <QMutexLocker>
#include <QMutex>

namespace YModbus {
	class Master;
};

class MODBUSTCPCLIENT_EXPORT cModbusItem : public QThread
{
	Q_OBJECT

public:
	cModbusItem(QObject *parent = 0);
	~cModbusItem();
public:
	bool connect(QString strIp, int nPort);
	bool isConnected();
	void setServerId(int nId);
	int getServerId();

	void release();

	bool getBit(uint16_t uAddr, uint16_t uBit);
	bool readRegister16(uint16_t uAddr, uint16_t &uValue);
	bool readRegister32(uint16_t uAddr, uint32_t &uValue);
	bool readCoil(uint16_t uAddr);

	bool setBit(uint16_t uAddr, uint16_t uBit, bool bState);
	bool writeRegister16(uint16_t uAddr, uint16_t uValue);
	bool writeRegister32(uint16_t uAddr, uint32_t uValue);
	bool writeCoil(uint16_t uAddr, bool bState);

private:
	void addValueCoilsHash(uint16_t uAddr);
	void addValueHoldingRegistersHash(uint16_t uAddr);

private:
	bool ctxReadRegister(uint16_t nStartAddress, int nNum);
	bool ctxReadCoil(uint16_t nStartAddress, int nNum);

	bool ctxWriteRegister(uint16_t nStartAddress, uint16_t uValue);
	bool ctxWriteCoil(uint16_t nStartAddress, bool bState);

protected:
	void run() override;

private:

	bool m_bConnected;
	bool m_bAppClose;
	bool m_bWriteRequestState;
	bool m_bReadRequestState;
	bool m_bReadNext;
	int m_nServerID;

	QString m_strIp;
	int m_nPort;
	QMutex m_mutex;
	YModbus::Master *m_pMaster;

private:
	QHash<uint16_t, uint16_t> m_readValueHoldingRegistersHash;
	QHash<uint16_t, uint16_> m_readAddrHoldingRegistersHash;

	QHash<uint16_t, uint16_t> m_readValueCoilsHash;
	QHash<uint16_t, uint16_t> m_readAddrCoilsHash;
};

2.源文件

代码如下:

#include "ModbusItem.h"
#include "ymblog.h"
#include "Ymod/ymbutils.h"
#include "Ymod/ymbtask.h"
#include "Ymod/ymbdefs.h"
#include "Ymod/Master/ymbmaster.h"
#include "Ymod/Master/ymaster.h"

#include <QVariant>
#include <QDebug>
#include <QTime>
#include <QVector>
#include <QTimer>
#define  COILS_READ_COUNT			       100
#define  HOLDING_REGISTERS_READ_COUNT	   100

struct sModbusTimer
{
	QTime time;
	uint32_t interval;

	void start(uint32_t t)
	{
		interval = t;
		time.restart();
	};

	bool isTimeOut()
	{
		return time.elapsed() > interval;
	};
};

cModbusItem::cModbusItem(QObject *parent)
	: QThread(parent)
	, m_bConnected(false)
	, m_bAppClose(false)
	, m_bWriteRequestState(false)
	, m_bReadRequestState(false)
	, m_bReadNext(true)
	, m_nServerID(1)
	, m_strIp("")
	, m_nPort(-1)
	, m_pMaster(nullptr)
{
	this->start();
}

cModbusItem::~cModbusItem()
{
	m_bAppClose = true;

	QThread::msleep(100);
}

void cModbusItem::run()
{
	static sModbusTimer timeout;
	static int nMainStep = 0;
	while (true)
	{
		if (m_bAppClose)
			return;

		switch (nMainStep)
		{
		case 0:
		{
			if (m_bConnected)
				nMainStep = 1;
			else
				QThread::msleep(500);

		}break;

		case 1:
		{
			if (true)
			{
				static int nIndex = 0;
				QHash<uint16_t, uint16_t> readAddrHoldingRegistersHashTemp;
				readAddrHoldingRegistersHashTemp = m_readAddrHoldingRegistersHash;
				auto keys = readAddrHoldingRegistersHashTemp.keys();

				if (keys.size() > 0)
				{
					nIndex = nIndex < keys.size() ? nIndex : 0;
					uint16_t uAddr = keys[nIndex];
					int nRead = uAddr - (HOLDING_REGISTERS_READ_COUNT / 2);

					// 从中间覆盖读取
					ctxReadRegister(nRead < 0 ? 0 : nRead, readAddrHoldingRegistersHashTemp[uAddr]);
					nIndex++;
				}

			}

			if (true)
			{
				static int nIndex = 0;
				QHash<uint16_t, uint16_t> readAddrCoilsHashTemp;
				readAddrCoilsHashTemp = m_readAddrCoilsHash;
				auto keys = readAddrCoilsHashTemp.keys();

				if (keys.size() > 0)
				{
					nIndex = nIndex < keys.size() ? nIndex : 0;
					uint16_t uAddr = keys[nIndex];

					// 从中间覆盖读取
					int nRead = uAddr - COILS_READ_COUNT / 2;
					ctxReadCoil(nRead < 0 ? 0 : nRead, readAddrCoilsHashTemp[uAddr]);
					nIndex++;
				}

			}

		}break;

		default:
			break;
		}
	}
}

// 连接
bool cModbusItem::connect(QString strIp, int nPort)
{
	if (m_bConnected)
		return true;

	char *chIp;
	QByteArray ba = strIp.toLatin1();
	chIp = ba.data();

	m_pMaster = new YModbus::Master(chIp, nPort, YModbus::TCP, YModbus::POLL);

	if (!m_pMaster->CheckConnect())
	{
		m_bConnected = false;
		delete m_pMaster;
		m_pMaster = nullptr;
	}
	else
	{
		m_bConnected = true;
	}

	m_strIp = strIp;
	m_nPort = nPort;

	return m_bConnected;
}

// 是否连接
bool cModbusItem::isConnected()
{
	return m_bConnected;
}

void cModbusItem::setServerId(int nId)
{
	m_nServerID = nId;
}

int cModbusItem::getServerId()
{ 
	return m_nServerID; 
}

void cModbusItem::release()
{
	m_bAppClose = true;

	QThread::msleep(30);

}

// 读取16位值
bool cModbusItem::readRegister16(uint16_t uAddr, uint16_t &uValue)
{
	if (!m_bConnected)
		return false;
	
	// 如果值读取哈希链表没有找到,需要插入到地址哈希链表,让它在后台读取
	auto itFind = m_readValueHoldingRegistersHash.find(uAddr);
	if (itFind == m_readValueHoldingRegistersHash.end())
	{
		m_readAddrHoldingRegistersHash[uAddr] = HOLDING_REGISTERS_READ_COUNT;

		if (true)
		{
			// 如果没有就先读取一次
			QHash<uint16_t, uint16_t> readAddrHoldingRegistersHashTemp;
			readAddrHoldingRegistersHashTemp = m_readAddrHoldingRegistersHash;
			int nRead = uAddr - (HOLDING_REGISTERS_READ_COUNT / 2);
			ctxReadRegister(nRead < 0 ? 0 : nRead, readAddrHoldingRegistersHashTemp[uAddr]);

			auto itFindItem = m_readValueHoldingRegistersHash.find(uAddr);
			if (itFindItem == m_readValueHoldingRegistersHash.end())
				return false;
			else
				uValue = m_readValueHoldingRegistersHash[uAddr];
		}
	}
	else
	{
		// 找到值,直接返回
		uValue = m_readValueHoldingRegistersHash[uAddr];
	}

	return true;
}

// 读取32位值
bool cModbusItem::readRegister32(uint16_t uAddr, uint32_t &uValue)
{
	if (!m_bConnected)
		return false;

	bool bRet = false;
	uint16_t uData16[2] = { 0 };
	bRet = readRegister16(uAddr, uData16[0]);
	bRet = readRegister16(uAddr + 1, uData16[1]);

	uValue = uData16[0]  | (uData16[1] << 16);

	return bRet;
}

// 获取位值
bool cModbusItem::getBit(uint16_t uAddr, uint16_t uBit)
{
	if (!m_bConnected)
		return false;

	uint16_t uValue = 0;
	readRegister16(uAddr, uValue);

	return uValue & (1 << (uBit % 16));
}

// 读取线圈值
bool cModbusItem::readCoil(uint16_t uAddr)
{
	bool bResult = false;
	uint16_t uValue = 0;

	auto itFind = m_readValueCoilsHash.find(uAddr);
	if (itFind == m_readValueCoilsHash.end())
	{
		m_readAddrCoilsHash[uAddr] = COILS_READ_COUNT;

		if (true)
		{
			QHash<uint16_t, uint16_t> readAddrCoilsHashTemp;
			readAddrCoilsHashTemp = m_readAddrCoilsHash;

			// 从中间覆盖读取
			int nRead = uAddr - COILS_READ_COUNT / 2;
			ctxReadCoil(nRead < 0 ? 0 : nRead, readAddrCoilsHashTemp[uAddr]);

			auto itFindItem = m_readValueCoilsHash.find(uAddr);
			if (itFindItem == m_readValueCoilsHash.end())
				bResult = false;
			else
				uValue = m_readValueCoilsHash[uAddr];

		}

		bResult = false;
	}
	else
		uValue = m_readValueCoilsHash[uAddr];

	if (true)
	{
		int nAddrSize = m_readAddrCoilsHash.size();
		int nValueSize = m_readValueCoilsHash.size();
	}

	uValue == 1 ? bResult = true : bResult = false;
	
	return bResult;
}

// 设置位值
bool cModbusItem::setBit(uint16_t uAddr, uint16_t uBit, bool bState)
{
	bool bRet = false;

	uint16_t uValue = 0;
	bRet = readRegister16(uAddr, uValue);

	if (bRet)
	{
		if (bState)
			uValue |= (1 << (uBit % 16));	 // 把某位置1
		else
			uValue &= ~(1 << (uBit % 16));	 // 把某位置0

		writeRegister16(uAddr, uValue);
	}

	return bRet;
}

// 写入16位值
bool cModbusItem::writeRegister16(uint16_t uAddr, uint16_t uValue)
{
	bool bRet = true;
	ctxWriteRegister(uAddr, uValue);
	return bRet;
}

// 写入32位值
bool cModbusItem::writeRegister32(uint16_t uAddr, uint32_t uValue)
{
	bool bRet = false;

	uint16_t uData16[2] = {0};
	uData16[0] = uValue & 0Xffff;
	uData16[1] = (uValue >> 16) & 0Xffff;

	bRet = writeRegister16(uAddr, uData16[0]);
	bRet = writeRegister16(uAddr+1, uData16[1]);

	return bRet;
}

// 写入线圈值
bool cModbusItem::writeCoil(uint16_t uAddr, bool bState)
{
	ctxWriteCoil(uAddr, bState);
	
	return true;
}

// 添加线圈数据列表
void cModbusItem::addValueCoilsHash(uint16_t uAddr)
{
	int nAddrStart = uAddr - (COILS_READ_COUNT / 2);
	if (nAddrStart < 0)
		nAddrStart = 0;

	//	提前添加数据列表,避免重复查询
	for (size_t i = 0; i < COILS_READ_COUNT; i++)
	{
		m_readValueCoilsHash[nAddrStart + i] = 0;
	}
}

// 添加保持寄存器数据列表
void cModbusItem::addValueHoldingRegistersHash(uint16_t uAddr)
{
	int nAddrStart = uAddr - (HOLDING_REGISTERS_READ_COUNT / 2);
	if (nAddrStart < 0)
		nAddrStart = 0;

	//	提前添加数据列表,避免重复查询
	for (size_t i = 0; i < HOLDING_REGISTERS_READ_COUNT; i++)
	{
		m_readValueHoldingRegistersHash[nAddrStart + i] = 0;
	}
}

//	读取寄存器
bool cModbusItem::ctxReadRegister(uint16_t nStartAddress, int nNum)
{
	if (!m_bConnected || m_pMaster == nullptr)
		return false;

	m_mutex.lock();
	static uint8_t buf[BUFSIZ] = { 0 };
	memset(buf, 0, sizeof(buf));
	int nLen;

	nLen = m_pMaster->ReadHoldingRegisters(m_nServerID, nStartAddress, nNum, buf, sizeof(buf));
	if (nLen == (nNum*2) && nLen != 0)
	{
		QList<uint16_t> uReadDataList;
		for (int i = 0; i < nLen; i++)
		{
			if ((i %2) ==0 )
			{
				uint16_t uValue = (buf[i] << 8) | buf[i+1];
				uReadDataList << uValue;
			}

		}
		//	写入数据哈希表
		for (size_t i = 0; i < uReadDataList.size(); i++)
		{

			m_readValueHoldingRegistersHash[nStartAddress + i] = uReadDataList[i];
		}
	}
	
	m_mutex.unlock();
	return true;
}

//	读取线圈
bool cModbusItem::ctxReadCoil(uint16_t nStartAddress, int nNum)
{
	if (!m_bConnected || m_pMaster == nullptr)
		return false;

	m_mutex.lock();
	static uint8_t buf[BUFSIZ] = { 0 };
	memset(buf, 0, sizeof(buf));
	int nLen;

	nLen = m_pMaster->ReadCoils(m_nServerID, nStartAddress, nNum, buf, sizeof(buf));
	if (nLen > 0)
	{
		QList<uint16_t> uReadDataList;
		for (int i = 0; i < nLen; i++)
		{
			uint16_t uValue = buf[i];
			uReadDataList << uValue;
		}
		//	写入数据哈希表
		for (size_t i = 0; i < nNum; i++)
		{
			int nIndex = i / 8;
			if (nIndex >= 0 && nIndex < uReadDataList.size())
			{
				int nBit = i - (8)*nIndex;
				if (nBit >= 0 && nBit < 8)
				{
					uint16_t uValue = (uReadDataList[nIndex] & (1 << nBit)) > 0 ? 1 : 0;
					m_readValueCoilsHash[nStartAddress + i] = uValue;
				}
			}
		}
	}

	m_mutex.unlock();
	return true;
}

bool cModbusItem::ctxWriteRegister(uint16_t nStartAddress, uint16_t uValue)
{
	m_mutex.lock();
	int nLen = m_pMaster->WriteSingleRegister(m_nServerID, nStartAddress, uValue);
	m_mutex.unlock();
	return true;
}

bool cModbusItem::ctxWriteCoil(uint16_t nStartAddress, bool bState)
{
	m_mutex.lock();
	int nLen = m_pMaster->WriteSingleCoil(m_nServerID, nStartAddress, bState);
	m_mutex.unlock();
	return true;
}



三、下载链接

https://download.csdn.net/download/u013083044/87062401

请添加图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++基于开源Modbus Tcp 通讯应用客户端(稳定高效,多线程后台状态读取,不卡顿) 的相关文章

  • 插入多重集中:在该值第一次出现之前而不是最后一次出现之后

    正如标题所示 multiset 在所有相同值的范围末尾插入一个值 例如 在多重集中插入 21 2 2 3做到了1 2 2 new 2 3 如何在所有相同值的范围开头插入新值 例如 在多重集中插入 21 2 2 3应该使1 new 2 2 2
  • 在 C# 中格式化 Resharper 属性的支持字段

    有没有办法控制 Resharper 放置其支持字段的位置 目前 它试图让他们在班级中名列前茅 我希望他们能去到酒店的正上方 还没有
  • asm、asm 易失性内存和破坏性内存之间的区别

    在实现无锁数据结构和定时代码时 通常需要抑制编译器的优化 通常人们使用asm volatile with memory在 clobber 列表中 但有时你会看到asm volatile或者只是一个简单的asm破坏记忆 这些不同的语句对代码生
  • 如何防止函数中的隐式转换?

    我正在编写一个实用程序类 其中包含 IsEquals 和 IsGreaterThanEquals 等接受 double 类型参数的方法 当我将浮点值发送到方法时 它们会隐式转换为双精度值并进行比较 我不希望这种事发生 当我发送 float
  • Motif 库的水平绘制的 RowColumn 类 (C)?

    我正在使用 Motif Library 来完成我的工作 如果有人不熟悉这个库 您可以在这里找到文件列表https packages ubuntu com xenial amd64 libmotif dev filelist https pa
  • 带有成员 (operator[]) 函数的 invoke_result

    如何为成员函数正确调用invoke result 或者专门用于运算符成员函数 我试过std invoke result
  • 改装和授权标头

    目前 我正在向我的请求添加授权标头 如下所示 文件 SomeFile cs public interface ITestApi Get api test id Task
  • 如何使用 CMake 链接多个库

    我有一些与 DCMTK 相关的代码 如果我从命令行使用 g 我可以成功构建并运行它 这是代码 include dcmtk config osconfig h include dcmtk dcmdata dctk h int main Dcm
  • 更改 Json 中属性的键

    这些天我正在尝试制作一个 json 编辑器 与树视图一起使用 我确实更改了值函数 我也可以更改一些键 但我无法在对象中设置键 我可以设置值 SetValue ref JObject main JToken token JToken newV
  • 对指针列表进行排序

    我再次发现自己在 C 中的一些非常简单的任务上失败了 有时我希望我能从 Java 中的 OO 中学到所有知识 因为我的问题通常是从像 Java 一样思考开始的 无论如何 我有一个std list
  • “未定义对 clrscr() 的引用;” [复制]

    这个问题在这里已经有答案了 include
  • COM Interop 挂起会冻结整个 COM 系统。如何取消COM调用

    我正在使用通过 COM Interop 包装器公开的第三方 dll 然而 其中一个 COM 调用经常冻结 至少不会返回 为了至少让我的代码更加健壮 我异步包装了调用 getDeviceInfoWaiter is a ManualResetE
  • 获取上下文菜单的控制

    我有一个如下所示的上下文菜单 A 1 2 3 选择 1 2 或 3 后 我需要访问调用上下文菜单的对象 意思是如果这是 textbox1 的上下文菜单 那么我需要访问该对象 我该怎么做 忘了说了 这是一个WPF应用程序 所以我使用 Syst
  • 如何打开 Outlook 已接收和阅读电子邮件

    我们有 5 个人 使用同一封电子邮件通过 Outlook 回复客户 我想设计一个程序来打开所有已发送的电子邮件 阅读它们 打开它们 找到第一个人的签名 并在他 她的计数器中添加一个数字 以便我可以得出一些统计数据 关于如何打开 Outloo
  • 成员函数的Decltype

    class A int f int x int j return 2 decltype f p 给我错误 error decltype cannot resolve address of overloaded function 我不明白为什
  • 如何在mvc视图中的表中显示数据库数据

    在我的 MVC 应用程序中 我从数据库检索数据 我想在表格中显示退役数据 控制器代码 public ActionResult MyAccount var user User Identity Name string sThumbnails
  • 如何在 C 中将 int 和数组保存在共享内存中?

    我正在尝试编写一个程序 让子进程在 Linux 上相互通信 这些进程都是从同一个程序创建的 因此它们共享代码 我需要它们能够访问两个整数变量以及一个整数数组 我不知道共享内存是如何工作的 我搜索过的每一个资源除了让我困惑之外什么也没做 任何
  • 找出用户属于哪些组

    我有一个刚刚创建的 Windows 用户帐户 以 XYZ 为例 此 XYZ 属于我在计算机管理 gt 本地用户和组中创建的用户组和自定义组 因此 在属性中我看到该用户属于 2 个组 现在我想获取这些组并显示它们 有什么建议么 我已经这样做了
  • 系统.安全.加密与 PCLCrypto

    我们正在删除系统中的许多共享功能并将其移植到 PCL 库中 我在使用 PCLCrypto 时遇到问题 我正在获取数据库中的一些现有数据 并尝试使用相同的算法对其进行解密 我得到了值 但末尾有 16 个额外字节 这些字节都是垃圾 参见下面的代
  • 如何用纯色填充位图?

    我需要使用唯一的 RGB 颜色创建 24 位位图 分辨率 100x100 像素 并将生成的图像保存到磁盘 我目前使用的是SetPixel http msdn microsoft com en us library 6c7eyzyb aspx

随机推荐

  • 选址问题

    选址问题 设施选址问题 Facility Location Problem 自20世纪60年代初期以来 在运筹学中一直占据着中心位置 它来自于工厂 仓库 超市 学校 医院 图书馆 火车站 代理服务器 传感器等位置的确定问题 设施选址问题是N
  • 计算机添加usb网络打印机,方便实用!教您如何简单地将USB打印机更改为无线打印机!...

    将USB打印机更改为无线打印机 只需完成三个主要步骤即可 首先 硬件准备 首先 您需要拥有一个带有USB端口和openwrt的路由器 编辑器使用RG100A 作为打印服务器 性能要求不高 只需将最初插入计算机USB的打印电缆插入路由器的US
  • 使用EasyPoi轻松导入导出Excel文档

    提到Excel的导入导出 大家肯定都知道alibaba开源的EasyExcel 该项目的github地址为 https github com alibaba easyexcel 这个项目非常活跃 项目诞生的目的就是为了简化开发 降低内存消耗
  • SCJP认证试题(十一)

    author yaoyuan 10 package com sun scjp 11 public class Geodetics 12 public static final double DIAMETER 12756 32 kilomet
  • 追求极致速度,极简多模态预训练模型ViLT,推理速度比UNITER快60倍!(ICML2021)...

    关注公众号 发现CV技术之美 写在前面 视觉和语言预训练 VLP 提高了各种联合视觉和语言下游任务的表现 然而 当前的VLP方法严重依赖于图像特征提取的过程 其中大部分涉及区域监督 例如 目标检测 和卷积结构 例如 ResNet 他们存在以
  • ubuntu16.04安装CUDA、cuDNN GTX 1660Ti

    在安装之前需要先确定已经安装好与显卡适配的驱动 如果没有的话 下载驱动 https www nvidia cn Download index aspx lang cn 安装 https blog csdn net frothmoon art
  • PCL 计算空间三角形的面积

    目录 一 算法原理 1 空间三角形面积 2 参考文献 二 代码实现 三 结果展示 一 算法原理 1 空间三角形面积 空间三角形面积的计算公式为 A P P S 1 P
  • FreeRTOS韦东山视频前八节学习笔记

    RTOS架构的概念 裸机开发 while 1 WEIFAN LIAOTIAN 多任务并行在while 1 循环 FreeeRTOS while 1 creat task 喂饭 creay task 回信息 start scheduler 让
  • Java课程设计——学生信息管理系统(源码)

    项目简介 该项目可以分为三个模块 登录模块 主页面模块 信息储存模块 本系统完成了基本所需功能 界面清晰 操作简单又实用 基本满足了学校对学生信息的增添 查询 修改和删除等功能 且具有登录系统使该系统具有一定的安全性 大大减少了操作人员和用
  • jstl 格式化时间日期标签讲解

  • 使用Openjdk8和maven时出错:java.security.InvalidAlgorithmParameterException

    错误类型 Maven java lang RuntimeException Unexpected error java security InvalidAlgorithmParameterException the trustAnchors
  • 【PCL】基于法线的差异来分割点云

    基于法线差异来分割点云 1 法向量的计算及可视化 法线又称法向量 因为在三维的点云中 根据一个点的K近邻点或者一个点的radius半径范围内的点拟合一个平面 而垂直这个平面且经过改点的线称之为法向量 法向量是点云点到另一个点的有方向的线段
  • 在django项目里创建子路由

    首先创建一个django项目 然后开始创建子路由 创建django项目 1 在pycharm中创建一个Blog graden的django项目 注意环境要选择正确 2 在Blog graden项目的控制台中创建一个blog app 3 将t
  • BIO、NIO、AIO区别

    一 BIO NIO AIO特点 1 BIO的特点就是每次一个客户端接入 都要在服务端创建一个线程来服务于这个客户端 所以如果有很多个客户端 就会对应成千上万个服务端线程 这会导致服务端负载过高 甚至卡死 2 NIO是同步非阻塞io 客户端和
  • C++ opencv人脸识别框

    需求 视频实时定位人脸位置 并画框 类似效果如下 分析 取视频帧 每一帧其实就类似一张图片 利用opencv的人脸识别模块 检测每一帧并进行划线 处理完成后显示 最后组成就是动态的带人脸识别框的视频 解决方法 下面是每一帧数据的处理方法 加
  • Myeclipse破解失败&&error: unable to access jarfile cracker.jar解决方法

    我的情况是在cracker jar破解成功后 Myeclipse依旧显示不成功 破解方案如下 1 进入cmd 输入java jar cracker jar 成功则显示图形 失败则会显示 error unable to access jarf
  • 台式机安装Linux系统

    材料 台式机 U盘 内存大于8G CentOs7 步骤一 U盘启动电脑 启动成功画面 选择第一个 按E或者 Tab键 进行编辑 vmlinuz initrd initrd img inst stage2 hd LABEL CentOS x2
  • Android 10深色主题适配踩坑记录

    1 问题简述 Android 10 推出了深色主题 便于用户根据白天和夜晚自由切换合适的主题 在适配的过程中 要特别注意 切换主题会导致当前activity被重建 也就是会重新走一遍Activity的生命周期 就和横竖屏切换时会重新走生命周
  • MongoDB 日志太大

    MongoDB的日志增长的非常快 var所在的空间立即就占满了 即便换到还有一个磁盘分区保存日志 日志还是增长的非常快 磁盘眼看要告磬 有一个好办法 就是使用旋转日志 MongoDB的旋转日志有点怪 Linux下mongd服务接受一个kil
  • C++基于开源Modbus Tcp 通讯应用客户端(稳定高效,多线程后台状态读取,不卡顿)

    C 基于开源Modbus Tcp 通讯应用客户端 前言 一 演示效果 二 关键程序 1 头文件 2 源文件 三 下载链接 前言 使用多线程后台批量刷寄存器的状态 在某种程度上保证了上层接口读取的时候 不会卡顿 整体应用效果比较友好 程序应用