QT串口和数据库通信
创建串口

串口连接客户端并向服务器发送消息
client.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T14:11:20
#
#-------------------------------------------------QT += core gui network
QT += core gui serialportgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = client
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += main.cpp\widget.cppHEADERS += widget.hFORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>
#include <QSerialPort>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void InitClient();void InitWidget();private slots:void on_connect_bt_clicked();void OnReadData();void OnReadyData1();void on_open_bt_clicked();private:Ui::Widget *ui;QTcpSocket *m_pSocket;QSerialPort *m_pSerial;
};#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.InitClient();w.InitWidget();w.show();return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QHostAddress>
#include <QSerialPort>
#include <QSerialPortInfo>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);m_pSocket = NULL;m_pSerial = NULL;
}Widget::~Widget()
{delete ui;
}void Widget::InitClient()
{qDebug() << "Widget::InitClient() enter";if (NULL == m_pSocket){m_pSocket = new QTcpSocket(this);connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(OnReadData()));}qDebug() << "Widget::InitClient() exit";
}void Widget::on_connect_bt_clicked()
{qDebug() << "Widget::on_connect_bt_clicked() enter";QString strIP = ui->ip_edit->text();QString strPort = ui->port_edit->text();qDebug() << strIP << " " << strPort;if (strIP.length() == 0 || strPort.length() == 0){qDebug() << "input error";return;}if (NULL == m_pSocket){qDebug() << "socket error";return;}m_pSocket->connectToHost(QHostAddress("127.0.0.1"), strPort.toShort());if (m_pSocket->waitForConnected(3000)){qDebug() << "connect ok";}else{qDebug() << "connect error";}qDebug() << "Widget::on_connect_bt_clicked() exit";
}void Widget::OnReadData()
{QByteArray arr = m_pSocket->readAll();qDebug() << arr;
}void Widget::InitWidget()
{qDebug() << "Widget::InitWidget() enter";if (NULL == m_pSerial){m_pSerial = new QSerialPort(this);connect(m_pSerial, SIGNAL(readyRead()), this, SLOT(OnReadyData1()));}qDebug() << "Widget::InitWidget() exit";
}void Widget::OnReadyData1() //串口数据就绪槽函数,当串口有数据可读时,该函数会被调用
{qDebug() << "Widget::OnReadyData1() enter";QByteArray strData = m_pSerial->readAll(); // 读取所有数据,处理接收到的数据m_pSocket->write(strData.toStdString().data());qDebug() << "Widget::OnReadyData1() exit";
}void Widget::on_open_bt_clicked()
{qDebug() << "Widget::on_open_bt_clicked() enter";if (NULL == m_pSerial){qDebug() << "serial obj error";return;}QString strBt = ui->open_bt->text();if (strBt == "open"){QString strCom = ui->uart_com->currentText();if (strCom.length() == 0){qDebug() << "com port error";return;}m_pSerial->setPortName(strCom);m_pSerial->setBaudRate(QSerialPort::Baud9600);m_pSerial->setDataBits(QSerialPort::Data8);m_pSerial->setStopBits(QSerialPort::OneStop);m_pSerial->setParity(QSerialPort::NoParity);m_pSerial->setFlowControl(QSerialPort::NoFlowControl);if (!m_pSerial->isOpen()){if (m_pSerial->open(QIODevice::ReadWrite)){qDebug() << "open ok";ui->open_bt->setText("close");ui->uart_com->setEnabled(false);}else{qDebug() << "open error";}}}else{m_pSerial->close();ui->open_bt->setText("open");//ui->send_bt->setEnabled(false);ui->uart_com->setEnabled(true);}
qDebug() << "Widget::on_open_bt_clicked() exit";}
widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>692</width><height>468</height></rect></property><property name="windowTitle"><string>Widget</string></property><widget class="QLabel" name="label"><property name="geometry"><rect><x>30</x><y>140</y><width>72</width><height>15</height></rect></property><property name="text"><string>ip</string></property></widget><widget class="QLineEdit" name="ip_edit"><property name="geometry"><rect><x>110</x><y>140</y><width>181</width><height>21</height></rect></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>30</x><y>180</y><width>72</width><height>15</height></rect></property><property name="text"><string>port</string></property></widget><widget class="QLineEdit" name="port_edit"><property name="geometry"><rect><x>110</x><y>180</y><width>181</width><height>21</height></rect></property></widget><widget class="QPushButton" name="connect_bt"><property name="geometry"><rect><x>340</x><y>150</y><width>93</width><height>28</height></rect></property><property name="text"><string>connect</string></property></widget><widget class="QComboBox" name="uart_com"><property name="geometry"><rect><x>30</x><y>50</y><width>87</width><height>22</height></rect></property><item><property name="text"><string>com9</string></property></item></widget><widget class="QPushButton" name="open_bt"><property name="geometry"><rect><x>200</x><y>50</y><width>93</width><height>28</height></rect></property><property name="text"><string>open</string></property></widget></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
服务器接收数据并存储在数据库内
server.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T09:20:48
#
#-------------------------------------------------QT += core gui network
QT += core gui sqlgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = server
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += main.cpp\widget.cpp \db.cppHEADERS += widget.h \common.h \db.hFORMS += widget.ui
common.h
#ifndef _COMMON_H_
#define _COMMON_H_#include <QDebug>
#include <QTime>#define _TIME_ qPrintable(QTime::currentTime().toString("hh:mm:ss:zzz"))#define FUNCTION_ENTER qDebug("%s %s %d %s start!",__FILE__,__FUNCTION__,__LINE__,_TIME_);
#define FUNCTION_EXIT qDebug("%s %s %d %s end!",__FILE__,__FUNCTION__,__LINE__,_TIME_);#endif //_COMMON_H_
db.h
#ifndef _DB_H_
#define _DB_H_#include <QSqlDatabase>
#include <QSqlQuery>class DBManager
{
public:enum DBMANAGER_TYPE{DBMANAGER_OK = 0,DBMANAGER_ERR,};public:static DBManager * GetInstance();static void DestroyInstance();int ExecSql(QString strSql);int ExecSql(QString strSql, QSqlQuery &query);private:DBManager();~DBManager();void InitDb();private:static DBManager *m_pManager;QSqlDatabase m_db;
};#endif //_DB_H_
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void InitServer();void InitWidget();private slots:void OnNewConnection();void on_listen_bt_clicked();void Insert();void on_pushButton_2_clicked();private:Ui::Widget *ui;QTcpServer *m_pServer;
};#endif // WIDGET_H
db.cpp
#include "common.h"
#include "db.h"
#include <QSqlError>DBManager *DBManager::m_pManager = NULL;int DBManager::ExecSql(QString strSql, QSqlQuery &query)
{FUNCTION_ENTER;if (strSql.length() == 0){return DBMANAGER_ERR;}query = m_db.exec(strSql);if (m_db.lastError().isValid()){qDebug() << m_db.lastError().text();return DBMANAGER_ERR;}FUNCTION_EXIT;return DBMANAGER_OK;
}int DBManager::ExecSql(QString strSql)
{FUNCTION_ENTER;if (strSql.length() == 0){return DBMANAGER_ERR;}m_db.exec(strSql);if (m_db.lastError().isValid()){qDebug() << m_db.lastError().text();return DBMANAGER_ERR;}FUNCTION_EXIT;return DBMANAGER_OK;
}DBManager::DBManager()
{FUNCTION_ENTER;FUNCTION_EXIT;
}DBManager::~DBManager()
{FUNCTION_ENTER;FUNCTION_EXIT;
}DBManager *DBManager::GetInstance()
{FUNCTION_ENTER;if (NULL == m_pManager){m_pManager = new DBManager();m_pManager->InitDb();}FUNCTION_EXIT;return m_pManager;
}void DBManager::DestroyInstance()
{FUNCTION_ENTER;if (NULL != m_pManager){delete m_pManager;m_pManager = NULL;}FUNCTION_EXIT;
}void DBManager::InitDb()
{FUNCTION_ENTER;m_db = QSqlDatabase::addDatabase("QMYSQL");m_db.setHostName("localhost");m_db.setDatabaseName("text");m_db.setUserName("root");m_db.setPassword("123456");if (m_db.open()){qDebug() << "open ok";}FUNCTION_EXIT;
}
main.cpp
#include "widget.h"
#include <QApplication>
#include <QSqlDatabase> //sql驱动基础
#include <QSqlQuery>//sql查询相关
#include <QSqlError>//sql输出错误int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.InitServer();w.InitWidget();w.show();return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QHostAddress>
#include <QTcpSocket>
#include "common.h"
#include "db.h"
#include <QTableWidgetItem>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);m_pServer = NULL;
}Widget::~Widget()
{delete ui;
}void Widget::InitServer()
{qDebug() << "Widget::InitServer() enter";if (NULL == m_pServer){m_pServer = new QTcpServer(this);connect(m_pServer, SIGNAL(newConnection()), this, SLOT(OnNewConnection()));}qDebug() << "Widget::InitServer() exit";
}void Widget::InitWidget()
{FUNCTION_ENTER;ui->tableWidget->setColumnCount(2);ui->tableWidget->setRowCount(5);QStringList strList;strList << "id"<<"name" ;ui->tableWidget->setHorizontalHeaderLabels(strList);ui->tableWidget->setAutoScroll(true);ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);ui->tableWidget->setSelectionBehavior( QAbstractItemView::SelectRows);FUNCTION_EXIT;
}void Widget::OnNewConnection()
{qDebug() << "new connection";QTcpSocket *pTmp = m_pServer->nextPendingConnection();if (NULL != pTmp){connect(pTmp, SIGNAL(readyRead()), this, SLOT(Insert()));}
}void Widget::on_listen_bt_clicked()
{qDebug() << "Widget::on_listen_bt_clicked() enter";if (NULL == m_pServer){return;}QString strIP = ui->ip_edit->text();QString strPort = ui->port_edit->text();if (strIP.length() == 0 || strPort.length() == 0){qDebug() << "input error";return;}bool bRet = m_pServer->listen(QHostAddress(strIP), strPort.toShort());if (bRet == true){qDebug() << "server listen ok";}qDebug() << "Widget::on_listen_bt_clicked() enter";
}void Widget::Insert()
{FUNCTION_ENTER;DBManager *pTmp = DBManager::GetInstance();if (NULL == pTmp){qDebug() << "db error";}QTcpSocket *pTmps = (QTcpSocket *)sender();if (NULL == pTmps){qDebug() << "socket error";return;}QByteArray arr = pTmps->readAll();//qDebug() << arr;QString str(arr);QStringList list = str.split(" ");QString strSql = QString("insert into text2 (id,name) values ('%1', '%2')").arg(list.at(0)).arg(list.at(1));int iRet = pTmp->ExecSql(strSql);if (iRet != DBManager::DBMANAGER_OK){qDebug() << "insert data error";return;}FUNCTION_EXIT;
}void Widget::on_pushButton_2_clicked()
{FUNCTION_ENTER;DBManager *pTmp = DBManager::GetInstance();if (NULL == pTmp){qDebug() << "db error";}QString strSql = "select * from text2";QSqlQuery query;int iRet = pTmp->ExecSql(strSql, query);if (iRet != DBManager::DBMANAGER_OK){qDebug() << "select data error";return;}int i = 0;while(query.next()){int j = 0;for (j = 0; j < 2; j++){//qDebug() << query.value(j).toString();QTableWidgetItem *pItem = new QTableWidgetItem(query.value(j).toString());ui->tableWidget->setItem(i, j, pItem);}i++;}FUNCTION_EXIT;
}
widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>893</width><height>629</height></rect></property><property name="windowTitle"><string>Widget</string></property><widget class="QLabel" name="label"><property name="geometry"><rect><x>80</x><y>60</y><width>72</width><height>15</height></rect></property><property name="text"><string>ip</string></property></widget><widget class="QLineEdit" name="ip_edit"><property name="geometry"><rect><x>140</x><y>60</y><width>221</width><height>21</height></rect></property></widget><widget class="QLineEdit" name="port_edit"><property name="geometry"><rect><x>140</x><y>100</y><width>221</width><height>21</height></rect></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>70</x><y>100</y><width>71</width><height>21</height></rect></property><property name="text"><string>port</string></property></widget><widget class="QPushButton" name="listen_bt"><property name="geometry"><rect><x>400</x><y>100</y><width>93</width><height>28</height></rect></property><property name="text"><string>listen</string></property></widget><widget class="QTableWidget" name="tableWidget"><property name="geometry"><rect><x>60</x><y>170</y><width>531</width><height>301</height></rect></property></widget><widget class="QPushButton" name="pushButton_2"><property name="geometry"><rect><x>670</x><y>180</y><width>101</width><height>31</height></rect></property><property name="text"><string>select</string></property></widget></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
测试

相关文章:
QT串口和数据库通信
创建串口 串口连接客户端并向服务器发送消息 client.pro #------------------------------------------------- # # Project created by QtCreator 2024-07-02T14:11:20 # #-------------------------------------------------QT core gui network QT core gui…...
WebKitWebKit简介及工作流程
简介 引擎能够解析HTML、CSS、JavaScript等网页标准,从而将互联网内容呈现给用户。 WebKit的主要特点包括: 开源性:它是一个开源项目,任何人都可以查看、修改和贡献代码。跨平台:WebKit可以在多个操作系统上运行&am…...
架构分析(CPU:ARM vs RISC-V)
ARM N2 ARM V2 对比 N2和V2,整体架构具有一致性。保证 SiFive P870 P870 Pipeline Veyron V1...
使用 Docker Compose 部署 RabbitMQ 的一些经验与踩坑记录
前言 RabbitMQ 是一个功能强大的开源消息队列系统,它实现了高效的消息通信和异步处理。 本文主要介绍其基于 Docker-Compose 的部署安装和一些使用的经验。 特点 成熟,稳定消息持久化灵活的消息路由高性能,高可用性,可扩展性高支…...
前端八股速通(持续更新中...)
1、深拷贝和浅拷贝的区别 浅拷贝:浅拷贝是拷贝一层,引用类型共享地址。 如果属性是基本类型,拷贝的就是基本类型的值。 如果属性是引用类型,拷贝的就是内存地址。 意思是,当进行浅拷贝时,对于对象的每一…...
【语音识别和生成】语音识别和语音合成技术
语音识别和生成:语音识别和语音合成技术 目录 引言语音识别技术 语音识别的基本原理语音识别系统的组成语音识别的关键技术 语音合成技术 语音合成的基本原理语音合成系统的组成语音合成的关键技术 语音识别和生成的应用 智能助理智能家居语音翻译医疗健康教育和学…...
Redis#架构师面试题
1、Redis锁存在哪些问题及如何解决? 1、死锁问题 加过期时间设定 2、原子性问题 通过“set…nx...ex…”命令,将加锁、过期命令编排到一起,它们是原子操作了,可以避免死锁。 3、释放其他线程的锁问题 当过期时间设置小于线程…...
关于#define的使用方法总结
文章目录 #define 预处理指令一、#define宏定义二、查看预处理文件三、#define 的使用方法四、C语言宏中“#”和“##”的用法五、常见的宏定义总结六、常考题目 #define 预处理指令 #define 是 C 和 C 编程语言中的预处理指令,用于定义宏(macro…...
Unity顶点动画(Vertex Animation):创造动态视觉效果
在Unity中,顶点动画(Vertex Animation)是一种强大的技术,它允许开发者直接在顶点级别上操作和变形网格,从而实现各种动态视觉效果。顶点动画不依赖于骨骼绑定,因此非常适合模拟布料、流体、面部表情等复杂的动画效果。本文将探讨顶…...
WSL for Windows
1、安装 超详细Windows10/Windows11 子系统(WSL2)安装Ubuntu20.04(带桌面环境)_wsl安装ubuntu20.04-CSDN博客https://blog.csdn.net/weixin_44301630/article/details/122390018 注意,安装之后首次启动 Ubuntu 时&…...
Matlab freqz 代码简单实现
相关代码打开matlab源码也可以看到,这里做了简单实现,与源码并不完全一样。 实现代码 [h2 w2] freqzfir(data); [h1 w1] freqz(data); h2h2; h12 [h1, h2];[h4 w4] freqziir(b,a, 2001,true); [h3 w3] freqz(b,a, w4, whole); h4 h4; h34 h…...
待办app哪款好?高效待办软件推荐
在快节奏的现代生活中,一款高效的待办事项管理软件对于提升工作效率和个人时间管理至关重要。面对市场上众多的待办app,哪款才是你的最佳选择呢?经过深入体验和对比,我发现敬业签这款高效待办软件是个不错的选择。 敬业签的快速记…...
【OSCP系列】OSCP靶机-BTRsys-2.1(原创)
OSCP系列靶机—BTRsys-2.1 原文转载已经过授权 原文链接:Lusen的小窝 - 学无止尽,不进则退 (lusensec.github.io) 一、主机发现 二、端口扫描 1、快速扫描 2、全端口扫描 3、服务系统探测 4、漏洞探测 80端口扫到了一些目录,有wordpress框…...
攻坚克难岁月长,自主腾飞世界强——回顾近代中国数据库的发展与飞跃
前言 最近看了《中国数据库前世今生》纪录片,感触颇深,也是一直在思考到底该用何种方式起笔来回顾这段筚路蓝缕却又充满民族自豪感的历程。大概构思了一周左右吧,我想,或许还是应该从那个计算机技术在国内刚刚萌芽的年代开始讲起…...
WEB前端12-axios基础
Vue2-axios基础 1.axios基本概念 在现代的前端开发中,处理网络请求是至关重要的一部分。Axios 是一个流行的基于 Promise 的 HTTP 客户端,它可以在浏览器和 Node.js 环境中使用。它的设计简单易用,支持并行请求、拦截器、CSRF 防护等特性&a…...
Ubuntu 防火墙设置
目录 1. 安装防火墙 2. 开启和关闭防火墙 3. 开放端口和服务规则 4. 关闭端口和删除服务规则 5. 查看防火墙状态 1. 安装防火墙 如果已经安装就忽略 # 安装ufw(Uncomplicated Firewall),这是Ubuntu上管理防火墙的一个简单工具 sudo ap…...
JL 跳转指令的理解
一般情况下,JU 和 JC 是最常见的跳转指令;但有时会用到JL 指令,JL 说起来更像是一组指令,类似C,C# 语言中的 switch case 语句,但是有个明显的不同,前者的判断条件可以是任意合理数字,后者范围…...
vue大屏展示组件库datav
主要用于构建大屏数据展示页面,具有多种类型组件可供使用。详情参考 datav官网 一、安装 npm 安装 npm install jiaminghi/data-viewyarn安装 yarn add jiaminghi/data-view二、使用 在main.js中注册为全局组件 import dataV from jiaminghi/data-view Vue.us…...
Vue.js 与 Ajax(vue-resource)的集成应用
Vue.js 与 Ajax(vue-resource)的集成应用 Vue.js 是一款流行的前端JavaScript框架,以其简洁、灵活和高效的特点而受到开发者的喜爱。在实际开发中,与后端服务的通信是不可或缺的,而Ajax技术是实现这一功能的关键。在V…...
【讲解下AI Native应用中的模型微调】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
