Modbus是一种常见的工业系统通讯协议。在我们的设计开发工作中经常使用到它。作为一种主从协议,在上一篇我们实现了Mobus RTU主站工具,接下来这一篇中我们将简单实现一个基于QT的Mobus RTU从站工具。
1、概述
Modbus RTU从站应用很常见,有一些是通用的,有一些是专用的。而这里我们希望实现一个主要针对我们的产品调试的Modbus RTU从站工具。 在开始软件设计之前,我们先来简略地分析一下,实现这样一个Modbus RTU从站工具包含的主要内容有哪些。我们认为软件需要如下几个方面的内容:
(1)、串口参数的配置
Modbus RTU通过串口来实现通讯,所以我们需要对串口相关的参数进行配置。我们希望串口号能够自动搜索,而相应的配置参数我们可以选择。 对串口的操作我们希望可以适应不同使用情况下的需求,让使用者可以自行选择串口名、波特率、校验位、数据位和停止位等,并控制串口的打开和关闭。
(2)、对数据的配置
数据的修改及更新,因为我们是从站实例,所以我们需要设置从站的参数类型和数量。我们将实现Modbus协议规定的4中数据类型:线圈、状态、输入寄存器和保持寄存器。 这四种数据其中线圈和状态是布尔量;输入寄存器和保持寄存器是16位整型量,这是指他的存储形式,事实上多个寄存器可以表示各种应用数据类型;线圈和保持寄存器支持读写;状态和输入寄存器位只读。
(3)、对主站的响应
对读从站数据,主要是指Modbus的功能码0x01、0x02、0x03和0x04等的处理。收到这几个功能码后,我们根据报文中的首地址和数量返回给主站即可。 对写从站数据,主要是指Modbus的功能码0x05、0x06、0x0F和0x10等的处理。对于这几个功能码,我们解析到这几个功能码后,根据指定的起始地址和数值对显影的变量值进行修改。
(4)、对信息的显示
接收信息的显示,作为调试工具,我们肯定希望能够一目了然地看到接收到目标设备发送过来的消息,所以我们需要一个显示区域来对接收的区域进行显示。 对数据的显示,我们在界面上设计各种数据类型的指示,线圈和状态使用CheckBox来显示其状态。当置位时现实为选中,复位时显示为不选中。而对于输入寄存器和保 持寄存器则可以直接显示它的数值。变量数据改变时则更新界面显示;同时界面状态改变时则更行变量数据。 运行状态的显示, 我们希望对操作的状态进行反馈以指示操作的动作是否执行,所以我们需要状态栏来实现这一需求。
2、界面设计
根据上一节中分析的需求,我们先来设计软件的界面。我们在QT中基于QMainWindow类生成一个操作界面,包括菜单栏、工具栏和状态栏以满足需求中对状态显示及操作命令的要求。 我们将上部区域设置为串口参数及Modbus RTU从站参数的配置于操作区域。而下面我们以5列17行的形式展示各种数据类型的数据状态。具体的界面设置如下图所示:
完成如上图的布局后,我们可以配置相应的参数,我们在程序初始化时配置好串口及Modbus RTU从站的默认参数。完成整个布局后我们先试着运行程序,正常运行则出现如下的界面:
上图就是完成布局后的运行界面,不过我们还没有实现相应的编码,所以目前还不能实现我们第一节中所提出来的功能。
3、编码实现
接下来这一小节,我们将来编码实现相应的功能。我们主要将功能分为参数设置与操作功能、数据的输入与发送功能以及数据的接收与显示功能三个部分来实现。
3.1、串口配置功能
对于参数的配置除了串口号以外,我们可以在程序中默认设置相应的参数,如果有必要可以修改,如果默认参数能满足要求亦可直接使用。至于串口号默认的不一定时我们所希望的,根据硬件配置情况选择即可。参数选定后我们只需要点击“连接”按钮即可实现Modbus RTU从站的连接。而连接操作的具体实现方式如下:
void MainWindow::on_pushButtonConnect_clicked()
{
bool intendToConnect = (modbusDevice->state() == QModbusDevice::UnconnectedState);
statusBar()->clearMessage();
if (intendToConnect)
{
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,ui->comboBoxPort->currentText());
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,QSerialPort::NoParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,ui->comboBoxBaud->currentText().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,QSerialPort::OneStop);
modbusDevice->setServerAddress(ui->spinBoxStation->text().toInt());
if (!modbusDevice->connectDevice())
{
statusBar()->showMessage(tr("连接失败: ") + modbusDevice->errorString(), 5000);
}
else
{
ui->pushButtonConnect->setEnabled(false);
ui->pushButtonDisconnect->setEnabled(true);
}
}
}
3.2、对界面操作的响应
首先我们在界面上操作各个类型的变量时,我们希望变量中的数据会跟随我们的操作而改变,并能被从站访问到。对于4种类型的数据将采用类似的处理方式。 对于线圈和状态量,当我们在界面上点击复选框改变选中状态时,会触发对应的槽函数,并肩对应的编号作为参数传递进去,槽函数会处理将Modbus RTU从站定义的变量状态改为和复选框的状态一致。具体实现如下:
void MainWindow::coilChanged(int id)
{
if(!modbusDevice)
{
return;
}
QAbstractButton *button = coilButtons.button(id);
if (!modbusDevice->setData(QModbusDataUnit::Coils, quint16(id), button->isChecked()))
{
statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000);
}
}
void MainWindow::discreteInputChanged(int id)
{
if(!modbusDevice)
{
return;
}
QAbstractButton *button = discreteButtons.button(id);
if (!modbusDevice->setData(QModbusDataUnit::DiscreteInputs, quint16(id), button->isChecked()))
{
statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000);
}
}
对于输入寄存器和保持寄存器在界面上使用的LineEdit来显示数据值,所以当我们改变LineEdit的内容时,让其触发槽函数。在槽函数中我们将Modbus RTU从站对应的寄存器的值改为和LineEdit的内容一样。具体实现如下:
void MainWindow::setInputRegister(const QString &value)
{
if(!modbusDevice)
{
return;
}
const QString objectName = QObject::sender()->objectName();
if(inputRegisters.contains(objectName))
{
bool ok = true;
const quint16 id = quint16(QObject::sender()->property("ID").toUInt());
if (objectName.startsWith(QStringLiteral("inReg")))
{
if(!modbusDevice->setData(QModbusDataUnit::InputRegisters, id, value.toUShort(&ok, 16)))
{
statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),5000);
}
}
}
}
void MainWindow::setHoldingRegister(const QString &value)
{
if(!modbusDevice)
{
return;
}
const QString objectName = QObject::sender()->objectName();
if(holdingRegisters.contains(objectName))
{
bool ok = true;
const quint16 id = quint16(QObject::sender()->property("ID").toUInt());
qDebug()<setData(QModbusDataUnit::HoldingRegisters, id, value.toUShort(&ok, 16)))
{
statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),5000);
}
}
}
}
经过上面的处理之后,到我们在界面上操作时就会更新到Modbus RTU从站对应的数据变量。
3.3、对主站设置的响应
当后台数据被修改时,需要修改显示数据。如主站修改了Coil或者HoldingRegister数据时,需要修改显示信息。而Modbus从站对象有3个信号,分别是:
void errorOccurred(QModbusDevice::Error error)
void stateChanged(QModbusDevice::State state)
void dataWritten(QModbusDataUnit::RegisterType table, int address, int size)
当主站访问从站时,则会在不同状态下触发相应信号函数,我们需要实现这三个信号函数对应的槽函数就可以实现相应的操作。具体实现如下:
//根据从站的变化更新数据显示
void MainWindow::UpdateDisplayBySlave(QModbusDataUnit::RegisterType table, int address, int size)
{
qDebug()<<"table:"<data(QModbusDataUnit::Coils, quint16(address + i), &value);
coilButtons.button(address + i)->setChecked(value);
break;
}
case QModbusDataUnit::HoldingRegisters:
{
modbusDevice->data(QModbusDataUnit::HoldingRegisters, quint16(address + i), &value);
qDebug()<setText(text.setNum(value, 16));
break;
}
default:
break;
}
}
}
//设备错误处理
void MainWindow::HandleDeviceError(QModbusDevice::Error newError)
{
if (newError == QModbusDevice::NoError || !modbusDevice)
return;
statusBar()->showMessage(modbusDevice->errorString(), 5000);
}
//从站状态改变响应
void MainWindow::SlaveStateChanged(int state)
{
bool connected = (state != QModbusDevice::UnconnectedState);
ui->pushButtonConnect->setEnabled(!connected);
ui->pushButtonDisconnect->setEnabled(connected);
}
4、测试验证
完成了编码调试后,我们来对开发的这一工具进行一些测试。首先我们安装一个虚拟串口软件用以虚拟我们用于测试的串口。我们还需要一个Modbus的主站应用来测试从站,这里我们选择Modscan来实现这一过程。 我们使用虚拟串口来模拟一对串口COM4和COM5。我们在ModScan中打开4个串口分别对应4中数据变量,数量都是16个,并将串口参数设置为和从站默认的一致,然后将其连接到COM5,如下图所示:
同时设置好从站的参数,然后将其连接到串口COM4,具体如下图:
这样从站和主站就连接上了。我们接下来在从站界面上操作,看看主站的数据变化。我们在从站界面上将线圈量的0、2、4、6、8、10、12、14等置位,并将状态量的1、3、5、7、9、11、13、15等置位,并在主站中查看,具体如下:
上图中我们可以看到主站显示的数据与从站设置的数据是一致的,说明我们的设计结果正确。接下来我们在从站界面上的输入寄存器的值修改0x01~0x10,同时在主站将保持寄存器的第10个修改为0x04,具体如下:
接下来我们在主站中修改保持寄存器的值,我们将保持寄存器的值修改为一系列不同的值,具体如下:
我们可以看到从站的显示数据与主站的设置是一致的。到此我们就完成了对Modbus RTU从站的测试,结果与我们设计的一致。
源码:https://gitee.com/ErichMoonan/modbus-slave
欢迎关注:
你可能感兴趣的:(应用软件,笔记,qt,系统架构)
C++编程:从入门到精通的指南
zifeng0015
c++ java jvm
本文将引导读者走进C++编程的世界,从基础知识讲起,逐步深入到高级特性。无论你是编程新手还是希望提升C++技能的开发者,本文都将为你提供有价值的指导和建议。正文:一、C++简介C++是一种面向对象的编程语言,由BjarneStroustrup于1985年开发。它结合了C语言的低级特性和面向对象编程的高级特性,因此既适合进行系统级编程,也适合进行大型应用软件开发。二、C++基础变量和数据类型:C++
使用emit发射信号
郭涤生
qt 开发语言
使用emit发射信号使用emit发射信号语法发射一个无参数信号发射带参数信号使用emit发射信号在Qt中,emit是一个关键字,用于在信号槽机制中发射信号。信号槽机制是Qt的一个重要特性,用于在对象之间进行通信。当一个对象的状态发生变化时,它可以发射一个信号,其他对象可以连接这个信号并在信号被发射时执行一些操作。语法emit用于发射信号,它的语法如下:emitsignalName(paramete
数学建模清风课程笔记——第二章 TOPSIS法
minpengyuanBITer
数学建模 数学建模 笔记
TOPSIS(TechniqueforOrderPreferencebySimilaritytoIdealSolution)可翻译为逼近理想解排序法,国内简称为优劣解距离法。TOPSIS法是一种常用的综合评价方法,其能充分利用原始数据的信息,其结果能够精确地反映各评价方案之间的差距。评价类问题1TOPSIS法TOPSIS法概念:TOPSIS法是一种常用的综合评价方法,能充分利用原始数据的信息,其结
JDK8 Stream 数据流效率分析,Java开发你需要了解的那些事
气质大叔
程序员 后端 面试 java
此外还有一系列特化流,如IntStream,LongStream,DoubleStream等),Java8引入的的Stream主要用于取代部分Collection的操作,每个流代表一个值序列,流提供一系列常用的聚集操作,可以便捷的在它上面进行各种运算。集合类库也提供了便捷的方式使我们可以以操作流的方式使用集合、数组以及其它数据结构;作为阅读福利,小编也整理了一些Java学习笔记(包含面试真题+脑图
前端面经分享(25/03/18)
CreatorRay
react 面试 前端 前端 面试 react
北京一家做边缘云服务提供商公司,技术一面,15k-20k,要求3-5年上家公司的项目为什么会选择MQTT进行通信React常用Hook为什么React不能在条件语句里用Hook前端常见的优化策略React如何捕获子组件的错误React给节点加key会有什么效果最近俩家公司都用WebSocket做了什么HTTP各个版本的区别跨域的常见解决方案前端常见布局WebSocket和SSE的区别A页面滚动到一
计算机网络笔记、面试八股(二)—— HTTP协议
Your_Raymond
计算机网络 http 计算机网络 面试
本章目录2.HTTP协议2.1HTTP协议简介2.2HTTP协议的优点2.3HTTP协议的缺点2.4HTTP协议属于哪一层2.5HTTP通信过程2.6常见请求方法2.7GET和POST的区别2.8请求报文与响应报文2.8.1HTTP请求报文2.8.2HTTP响应报文2.9响应状态码2.10HTTP1.0和1.1的区别2.10.1长连接2.10.2错误响应码2.10.3缓存处理2.10.4带宽的优化
Python + Qt Designer构建多界面GUI应用程序:Python如何调用多个界面文件
懒大王爱吃狼
python python qt 命令模式 mysql 数据库 Python基础 开发语言
引言QtDesigner是一个用户友好的图形用户界面设计工具,它可以帮助开发人员通过拖放的方式快速创建界面。在实际开发中,往往需要设计多个界面文件,并在Python代码中进行统一管理和使用。本文将介绍如何在Python中使用QtDesigner设计好的多个界面文件的常用方法。方法一:单独加载并显示如果界面文件相对独立,并且没有复杂的依赖关系,可以考虑单独加载并显示每个界面文件。fromPyQt5i
linuxcentos6笔记
lnes,
linux centos vim
目录Linux笔记11目录结构51.1基本指令51.2Ls指令:51.3Pwd指令:61.4Cd指令:71.5mkdir指令:71.6touch指令:71.7cp指令:71.8mv指令:81.9rm指令:81.10vim指令:91.11输出重定向:91.12cat指令:102进阶指令102.1Df指令:102.2free指令:102.3head指令:112.4tail指令:112.5less指令:
【考研计算机网络】课堂笔记1 第一章 概述
刘鑫磊up
# 操作系统 计算机网络 计算机网络
文章目录:一:计算机网络的概述1.计算机网络的基本概念2.计算机网络的组成3.计算机网络的功能4.计算机网络的分类4.1分布范围分类4.2传输技术分类4.3按照拓扑结构分类4.4按照使用者分类4.5按照传输介质分类二:计算机网络的标准化工作及相关组织三:计算机网络的性能指标速率kb千Mb兆Gb吉Tb太的单位换算存储容量KBMBGBTB的单位换数四:网络分层五:计算机网络协议、接口、服务的概念1.协
常用的pdf技术有哪些?--笔记
我不是彭于晏灬
pdf 笔记
常用的pdf技术有哪些?1.iTextPDF:iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。Openoffice:openoffice是开源软件且能在windows和linux平台下运行,可以灵活的将word或者Excel转化为PDF文档。JasperReport:是一个强大、灵活
在嵌入式系统中实现低功耗MQTT协议:从协议解析到硬件优化
W说编程
物联网 嵌入式 网络编程 物联网 网络协议 c语言 嵌入式硬件
在嵌入式系统中实现低功耗MQTT协议:从协议解析到硬件优化1.引言:物联网时代的低功耗挑战随着物联网设备的爆炸式增长,设备续航与网络可靠性成为嵌入式系统设计的核心矛盾。据统计,70%的物联网设备因功耗问题导致维护成本倍增。核心需求:在维持TCP/IP协议栈功能的前提下,将设备待机功耗降至μA级;确保弱网环境(如2G/NB-IoT)下的数据传输可靠性。本文将以MQTT协议为例,详解在STM32+LW
计算机网络笔记再战——理解几个经典的协议HTTP章4
charlie114514191
计算机网络学习 计算机网络 笔记 http 学习 网络协议 网络
计算机网络笔记再战——理解几个经典的协议10HTTP章4确保Web安全的HTTPSHTTP是不安全的,它使用的是明文传递,这意味着潜在的报文纂改。这里我们将学习更加安全的HTTPS协议通信使用明文(不加密),内容可能会被窃听不验证通信方的身份,因此有可能遭遇伪装无法证明报文的完整性,所以有可能已遭篡改HTTP本身没有办法加密,但是可以跟SSL(SecureSocketLayer)或者是TLS(Tr
C++ 结构型设计模式
十七12138
C++ c++ 设计模式
C++设计模式自己理解整理笔记结构型-适配器模式适配器模式(AdapterPattern)是一种结构型设计模式,它的主要作用是将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式主要有两种实现方式:类适配器模式和对象适配器模式。类适配器类适配器通过多重继承实现,这种方式利用了继承优点直接调用:由于适配器类继承了被适配类,所以可以直接调用被适
numpy学习笔记3:三维数组 np.ones((2, 3, 4)) 的详细解释
宁宁可可
# 机器学习 # Python基础与进阶 numpy 学习笔记
numpy学习笔记3:三维数组np.ones((2,3,4))的详细解释以下是关于三维数组np.ones((2,3,4))的详细解释:1.三维数组的形状形状(2,3,4)表示:最外层维度:2个“层”(或“块”);中间维度:每个层有3行;最内层维度:每行有4个元素。可以类比为:2本书(外层),每本书有3页(中间层),每页有4行文字(内层)。2.创建全1三维数组代码示例:importnumpyasnp
【第11章】亿级电商平台订单系统-海量数据架构设计
cherry5230
架构 系统架构 架构 分布式
1-1本章导学课程导学课程定位:大型系统架构设计核心难点解析核心项目:BToB电商平台订单系统(年交易额200亿级)本章知识体系1.核心概念辨析海量数据vs大数据本质区别解析常见认知误区说明2.方法论框架海量数据处理核心思想分布式计算原理数据分片策略弹性扩展机制3.数据库架构设计方法论体系读写分离模式分库分表策略数据分区方案缓存层设计4.数据处理体系海量数据处理之道批处理与流处理数据压缩技术异步处
qt-5.15.2 源码编译 Linux
weixin_40857106
服务器 运维
QT官方源码下载地址:https://download.qt.io/archive/qt/5.15/5.15.12/single/qt-everywhere-opensource-src-5.15.12.tar.xz安装Qt所需的依赖:sudoaptinstallbuild-essentiallibgl1-mesa-devlibxkbcommon-devlibnss3-devlibdbus-1-d
Ts学习笔记
初学者7.
学习 笔记 typescript
一、Ts与Js区别TsJsJavaScript的超集,用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页。强类型,支持静态和动态类型动态弱类型语言可以在编译期间发现并纠正错误只能在运行时发现错误不允许改变变量的数据类型变量可以被赋予不同类型的值二、Ts基础类型:boolean,number,string,undefined,null,any,unknown,void,neverany,un
QT引用资源qrc
我该叫什么名字好呢?
QT开发 QT qtcreator 文本编辑 控件
1.在工程文件夹下面添加一个文件夹,如images,保存图标文件.2.在工程那里新建一个qrc文件,右键选择文本编辑器打开添加如下语句:images/file_128.icoimages/open_128.icoimages/save_128.ico这样工程就能读取到这些资源,在要设置图标的控件的icon选项,选择资源文件,就可以使用图标了。3.假如是利用QTcreator编写的,那就比较简单,直
Qt爬坑笔记
klzed_
qt c++ 后端 ui
1.自定义一个QWidget的派生类,将其作为子部件并设置样式表时,需要重写paintEvent事件,否则样式表可能无效,如下所示:voidCustomWidget::paintEvent(QPaintEvent*){QStyleOptionopt;opt.init(this);QPainterp(this);
LeetCode刷题笔记
小李李李李腊八
leetcode 算法 java
leetcode_01两数之和斐波那契数列三个数最大乘积反转链表x的平方根环形列表LeetCode随笔两数之和给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。暴力法记录下数组第一个数值,对数组进行循环,将之后的值
系统架构设计(以飞控系统、航电系统、机电管理系统、电子电气架构为例)
机载软件与适航
机载系统 系统工程 适航 系统架构 架构
架构的定义系统架构涉及对系统的结构和行为进行高层次的描述。它包括系统的组成部分、这些部分之间的关系、与外部环境的交互方式,以及满足特定功能和非功能性需求的方法。系统架构定义了系统的总体设计蓝图,指导系统的开发、集成、部署和维护。系统架构的核心要素组成部分(Components):系统中的独立模块或单元,每个模块执行特定的功能。组件可以是软件模块、硬件设备、数据库、用户界面等。组件间的关系(Rela
numpy学习笔记2:ones = np.ones((2, 4)) 的详解
宁宁可可
# 机器学习 # Python基础与进阶 numpy python 开发语言
numpy学习笔记2:ones=np.ones((2,4))的详解np.ones()是NumPy中用于创建全1数组的核心函数,其用法和参数与np.zeros()类似,但生成的数组元素值全部为1。以下是详细解释:1、语法numpy.ones(shape,dtype=float,order='C')作用:生成一个指定形状和数据类型的全1数组。参数:shape:数组的形状,以元组形式传递(如(2,4)表
软考 中级软件设计师 考点知识点笔记总结 day05
莫问alicia
软考 中级软件设计师 笔记 算法
文章目录4、栈和队列4.1、栈的定义4.2、队列定义5、串、数组、矩阵和广义表5.1、串5.2、数组5.3、稀疏矩阵5.4、广义表4、栈和队列4.1、栈的定义线性表是具有相同数据类型的n个数据元素的有限序列,n为表厂。n=0时线性表是一个空表L=(a1,a2,a3,…an)栈是只允许在一端进行插入或删除操作的线性表栈顶允许插入和删除的一端栈顶进栈顶出栈底不允许插入和删除的一端4.2、队列定义队列是
Ubuntu Qt: no service found for - “org.qt-project.qt.mediaplayer“
wkm956
qt 开发语言 ubuntu
1、前言在一次项目过程中,因项目需求,需要将windows开发的Qt项目迁移到ubuntu系统中,且在某个功能项中需要播放音频,在windows系统中能够正常运行,但在ubuntu系统中却显示defaultServiceProvider::requestService():noservicefoundfor-"org.qt-project.qt.mediaplayer"错误,在网上查找资料后解决问
numpy学习笔记10:arr *= 2向量化操作性能优化
宁宁可可
# 机器学习 # Python基础与进阶 numpy 学习笔记
numpy学习笔记10:arr*=2向量化操作性能优化在NumPy中,直接对整个数组进行向量化操作(如arr*=2)的效率远高于显式循环(如foriinrange(len(arr)):arr[i]*=2)。以下是详细的解释:1.性能差异的原理(1)底层实现不同显式循环(错误示范):Python的for循环是解释执行的,每次迭代需要动态解析变量类型、执行函数调用等操作。对每个元素的操作会触发多次Py
nginx性能优化有哪些方式?
企鹅侠客
linux 面试 nginx 性能优化 php
0.运维干货分享软考高级系统架构设计师备考学习资料软考高级网络规划设计师备考学习资料KubernetesCKA认证学习资料分享信息安全管理体系(ISMS)制度模板分享免费文档翻译工具(支持word、pdf、ppt、excel)PuTTY中文版安装包MobaXterm中文版安装包pinginfoview网络诊断工具中文版Nginx是一个高性能的HTTP服务器和反向代理服务器,但在高并发场景下,仍然有
在Qt代码中使用Windows事件机制WaitForMultipleObjects、SetEvent
令狐掌门
深入浅出C++ Qt开发技术 qt windows 开发语言 SetEvent
在Qt开发客户端时,经常使用信号槽来处理控件或窗口之间的事件,如果是Windows系统,也可以用windows事件来代替Qt的信号槽,本篇博客来介绍这种用法。首先需要介绍本篇本篇博客需要用到的几个WindowsAPI:一、需要用到的WindowsAPIWaitForMultipleObjectsWaitForMultipleObjects是WindowsAPI中一个用于同步操作的函数。它主要用于等
TCP、UDP、HTTP、WebSocket 和 MQTT协议区别
PHPlai
php tcp/ip udp http
目录1.TCP协议2.UDP协议3.HTTP协议4.WebSocket协议5.MQTT协议总结1.TCP协议类型:面向连接的协议。可靠性:提供可靠的数据传输,确保数据包按顺序到达。流量控制:具备流量控制与拥塞控制机制。适用场景:适合对数据传输可靠性要求高的应用,如文件传输、网页加载。2.UDP协议类型:无连接的协议。可靠性:不保证数据包的可靠传输,可能会丢失、重复或顺序错乱。流量控制:不具备流量控
HTTP、MQTT、CoAP大比拼:谁才是物联网通信的王者?
极客小张
物联网 http 网络协议 单片机 网络
物联网(IoT)时代,数以亿计的设备需要相互连接和通信,而超文本传输协议(HTTP)作为互联网的基石,凭借其简单易用、广泛应用等优势,也成为了物联网通信协议的有力竞争者。本文将深入浅出地剖析HTTP协议在物联网中的应用,从工作原理、优缺点、安全问题到未来发展趋势,带您全面了解HTTP在物联网世界中的角色和潜力。一、HTTP协议:物联网通信的通用语言1.1HTTP协议工作原理:请求与响应的循环HTT
QT信号和槽用于对象之间的通信
qq_33510982
c++ QT 信号与槽
转载:http://blog.csdn.net/zhang2531/article/details/50807616初学qt,觉得这篇关于qt信号和槽机制讲的最为透彻。信号和槽信号和槽用于对象间的通讯。信号/槽机制是Qt的一个中心特征并且也许是Qt与其它工具包的最不相同的部分。在图形用户界面编程中,我们经常希望一个窗口部件的一个变化被通知给另一个窗口部件。更一般地,我们希望任何一类的对象可以和其它
Java实现的基于模板的网页结构化信息精准抽取组件:HtmlExtractor
yangshangchuan
信息抽取 HtmlExtractor 精准抽取 信息采集
HtmlExtractor是一个Java实现的基于模板的网页结构化信息精准抽取组件,本身并不包含爬虫功能,但可被爬虫或其他程序调用以便更精准地对网页结构化信息进行抽取。
HtmlExtractor是为大规模分布式环境设计的,采用主从架构,主节点负责维护抽取规则,从节点向主节点请求抽取规则,当抽取规则发生变化,主节点主动通知从节点,从而能实现抽取规则变化之后的实时动态生效。
如
java编程思想 -- 多态
百合不是茶
java 多态详解
一: 向上转型和向下转型
面向对象中的转型只会发生在有继承关系的子类和父类中(接口的实现也包括在这里)。父类:人 子类:男人向上转型: Person p = new Man() ; //向上转型不需要强制类型转化向下转型: Man man =
[自动数据处理]稳扎稳打,逐步形成自有ADP系统体系
comsci
dp
对于国内的IT行业来讲,虽然我们已经有了"两弹一星",在局部领域形成了自己独有的技术特征,并初步摆脱了国外的控制...但是前面的路还很长....
首先是我们的自动数据处理系统还无法处理很多高级工程...中等规模的拓扑分析系统也没有完成,更加复杂的
storm 自定义 日志文件
商人shang
storm cluster logback
Storm中的日志级级别默认为INFO,并且,日志文件是根据worker号来进行区分的,这样,同一个log文件中的信息不一定是一个业务的,这样就会有以下两个需求出现:
1. 想要进行一些调试信息的输出
2. 调试信息或者业务日志信息想要输出到一些固定的文件中
不要怕,不要烦恼,其实Storm已经提供了这样的支持,可以通过自定义logback 下的 cluster.xml 来输
Extjs3 SpringMVC使用 @RequestBody 标签问题记录
21jhf
springMVC使用 @RequestBody(required = false) UserVO userInfo
传递json对象数据,往往会出现http 415,400,500等错误,总结一下需要使用ajax提交json数据才行,ajax提交使用proxy,参数为jsonData,不能为params;另外,需要设置Content-type属性为json,代码如下:
(由于使用了父类aaa
一些排错方法
文强chu
方法
1、java.lang.IllegalStateException: Class invariant violation
at org.apache.log4j.LogManager.getLoggerRepository(LogManager.java:199)at org.apache.log4j.LogManager.getLogger(LogManager.java:228)
at o
Swing中文件恢复我觉得很难
小桔子
swing
我那个草了!老大怎么回事,怎么做项目评估的?只会说相信你可以做的,试一下,有的是时间!
用java开发一个图文处理工具,类似word,任意位置插入、拖动、删除图片以及文本等。文本框、流程图等,数据保存数据库,其余可保存pdf格式。ok,姐姐千辛万苦,
php 文件操作
aichenglong
PHP 读取文件 写入文件
1 写入文件
@$fp=fopen("$DOCUMENT_ROOT/order.txt", "ab");
if(!$fp){
echo "open file error" ;
exit;
}
$outputstring="date:"." \t tire:".$tire."
MySQL的btree索引和hash索引的区别
AILIKES
数据结构 mysql 算法
Hash 索引结构的特殊性,其 检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。
可能很多人又有疑问了,既然 Hash 索引的效率要比 B-Tree 高很多,为什么大家不都用 Hash 索引而还要使用 B-Tree 索引呢
JAVA的抽象--- 接口 --实现
百合不是茶
抽象 接口 实现接口
//抽象 类 ,方法
//定义一个公共抽象的类 ,并在类中定义一个抽象的方法体
抽象的定义使用abstract
abstract class A 定义一个抽象类 例如:
//定义一个基类
public abstract class A{
//抽象类不能用来实例化,只能用来继承
//
JS变量作用域实例
bijian1013
作用域
<script>
var scope='hello';
function a(){
console.log(scope); //undefined
var scope='world';
console.log(scope); //world
console.log(b);
TDD实践(二)
bijian1013
java TDD
实践题目:分解质因数
Step1:
单元测试:
package com.bijian.study.factor.test;
import java.util.Arrays;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import com.bijian.
[MongoDB学习笔记一]MongoDB主从复制
bit1129
mongodb
MongoDB称为分布式数据库,主要原因是1.基于副本集的数据备份, 2.基于切片的数据扩容。副本集解决数据的读写性能问题,切片解决了MongoDB的数据扩容问题。
事实上,MongoDB提供了主从复制和副本复制两种备份方式,在MongoDB的主从复制和副本复制集群环境中,只有一台作为主服务器,另外一台或者多台服务器作为从服务器。 本文介绍MongoDB的主从复制模式,需要指明
【HBase五】Java API操作HBase
bit1129
hbase
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.ha
python调用zabbix api接口实时展示数据
ronin47
zabbix api接口来进行展示。经过思考之后,计划获取如下内容: 1、 获得认证密钥 2、 获取zabbix所有的主机组 3、 获取单个组下的所有主机 4、 获取某个主机下的所有监控项  
jsp取得绝对路径
byalias
绝对路径
在JavaWeb开发中,常使用绝对路径的方式来引入JavaScript和CSS文件,这样可以避免因为目录变动导致引入文件找不到的情况,常用的做法如下:
一、使用${pageContext.request.contextPath}
代码” ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。
Java定时任务调度:用ExecutorService取代Timer
bylijinnan
java
《Java并发编程实战》一书提到的用ExecutorService取代Java Timer有几个理由,我认为其中最重要的理由是:
如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。Timer线程并不捕获异常,所以 TimerTask抛出的未检查的异常会终止timer线程。这种情况下,Timer也不会再重新恢复线程的执行了;它错误的认为整个Timer都被取消了。此时,已经被
SQL 优化原则
chicony
sql
一、问题的提出
在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统
java 线程弹球小游戏
CrazyMizzz
java 游戏
最近java学到线程,于是做了一个线程弹球的小游戏,不过还没完善
这里是提纲
1.线程弹球游戏实现
1.实现界面需要使用哪些API类
JFrame
JPanel
JButton
FlowLayout
Graphics2D
Thread
Color
ActionListener
ActionEvent
MouseListener
Mouse
hadoop jps出现process information unavailable提示解决办法
daizj
hadoop jps
hadoop jps出现process information unavailable提示解决办法
jps时出现如下信息:
3019 -- process information unavailable3053 -- process information unavailable2985 -- process information unavailable2917 --
PHP图片水印缩放类实现
dcj3sjt126com
PHP
<?php
class Image{
private $path;
function __construct($path='./'){
$this->path=rtrim($path,'/').'/';
}
//水印函数,参数:背景图,水印图,位置,前缀,TMD透明度
public function water($b,$l,$pos
IOS控件学习:UILabel常用属性与用法
dcj3sjt126com
ios UILabel
参考网站:
http://shijue.me/show_text/521c396a8ddf876566000007
http://www.tuicool.com/articles/zquENb
http://blog.csdn.net/a451493485/article/details/9454695
http://wiki.eoe.cn/page/iOS_pptl_artile_281
完全手动建立maven骨架
eksliang
java eclipse Web
建一个 JAVA 项目 :
mvn archetype:create
-DgroupId=com.demo
-DartifactId=App
[-Dversion=0.0.1-SNAPSHOT]
[-Dpackaging=jar]
建一个 web 项目 :
mvn archetype:create
-DgroupId=com.demo
-DartifactId=web-a
配置清单
gengzg
配置
1、修改grub启动的内核版本
vi /boot/grub/grub.conf
将default 0改为1
拷贝mt7601Usta.ko到/lib文件夹
拷贝RT2870STA.dat到 /etc/Wireless/RT2870STA/文件夹
拷贝wifiscan到bin文件夹,chmod 775 /bin/wifiscan
拷贝wifiget.sh到bin文件夹,chm
Windows端口被占用处理方法
huqiji
windows
以下文章主要以80端口号为例,如果想知道其他的端口号也可以使用该方法..........................1、在windows下如何查看80端口占用情况?是被哪个进程占用?如何终止等. 这里主要是用到windows下的DOS工具,点击"开始"--"运行",输入&
开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !
天梯梦
mobile
CKplayer,其全称为超酷flv播放器,它是一款用于网页上播放视频的软件,支持的格式有:http协议上的flv,f4v,mp4格式,同时支持rtmp视频流格 式播放,此播放器的特点在于用户可以自己定义播放器的风格,诸如播放/暂停按钮,静音按钮,全屏按钮都是以外部图片接口形式调用,用户根据自己的需要制作 出播放器风格所需要使用的各个按钮图片然后替换掉原始风格里相应的图片就可以制作出自己的风格了,
简单工厂设计模式
hm4123660
java 工厂设计模式 简单工厂模式
简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式。是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
maven笔记
zhb8015
maven
跳过测试阶段:
mvn package -DskipTests
临时性跳过测试代码的编译:
mvn package -Dmaven.test.skip=true
maven.test.skip同时控制maven-compiler-plugin和maven-surefire-plugin两个插件的行为,即跳过编译,又跳过测试。
指定测试类
mvn test
非mapreduce生成Hfile,然后导入hbase当中
Stark_Summer
map hbase reduce Hfile path实例
最近一个群友的boss让研究hbase,让hbase的入库速度达到5w+/s,这可愁死了,4台个人电脑组成的集群,多线程入库调了好久,速度也才1w左右,都没有达到理想的那种速度,然后就想到了这种方式,但是网上多是用mapreduce来实现入库,而现在的需求是实时入库,不生成文件了,所以就只能自己用代码实现了,但是网上查了很多资料都没有查到,最后在一个网友的指引下,看了源码,最后找到了生成Hfile
jsp web tomcat 编码问题
王新春
tomcat jsp pageEncode
今天配置jsp项目在tomcat上,windows上正常,而linux上显示乱码,最后定位原因为tomcat 的server.xml 文件的配置,添加 URIEncoding 属性:
<Connector port="8080" protocol="HTTP/1.1"
connectionTi