当前位置: 首页 > news >正文

【在Linux世界中追寻伟大的One Piece】Socket编程UDP

目录

1 -> UDP网络编程

1.1 -> V1版本 -echo server

1.2 -> V2版本 -DictServer

1.3 -> V2版本 -DictServer(封装版)


1 -> UDP网络编程

1.1 -> V1版本 -echo server

简单的回显服务器和客户端代码。

备注:代码中会用到地址转换函数

nocopy.hpp

#pragma once
#include <iostream>class nocopy
{
public:nocopy() {}nocopy(const nocopy&) = delete;const nocopy& operator = (const nocopy&) = delete;~nocopy() {}
};

UdpServer.hpp

#pragma once
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nocopy.hpp"
#include "Log.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"const static uint16_t defaultport = 8888;
const static int defaultfd = -1;
const static int defaultsize = 1024;class UdpServer : public nocopy
{
public:UdpServer(uint16_t port = defaultport): _port(port), _sockfd(defaultfd){}void Init(){// 1. 创建 socket,就是创建了文件细节_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd < 0){lg.LogMessage(Fatal, "socket errr, %d : %s\n", errno,strerror(errno));exit(Socket_Err);}lg.LogMessage(Info, "socket success, sockfd: %d\n",_sockfd);// 2. 绑定,指定网络信息struct sockaddr_in local;bzero(&local, sizeof(local)); // memsetlocal.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY; // 0// local.sin_addr.s_addr = inet_addr(_ip.c_str()); // 1. 4字节 IP 2. 变成网络序列// 结构体填完,设置到内核中了吗??没有int n = ::bind(_sockfd, (struct sockaddr*)&local,sizeof(local));if (n != 0){lg.LogMessage(Fatal, "bind errr, %d : %s\n", errno,strerror(errno));exit(Bind_Err);}}void Start(){// 服务器永远不退出char buffer[defaultsize];for (;;){struct sockaddr_in peer;socklen_t len = sizeof(peer); // 不能乱写ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) -1, 0, (struct sockaddr*)&peer, &len);if (n > 0){InetAddr addr(peer);buffer[n] = 0;std::cout << "[" << addr.PrintDebug() << "]# " <<buffer << std::endl;sendto(_sockfd, buffer, strlen(buffer), 0, (structsockaddr*)&peer, len);}}}~UdpServer(){}private:// std::string _ip; // 后面要调整uint16_t _port;int _sockfd;
};

InetAddr.hpp

#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>class InetAddr
{
public:InetAddr(struct sockaddr_in& addr) :_addr(addr){_port = ntohs(_addr.sin_port);_ip = inet_ntoa(_addr.sin_addr);}std::string Ip() { return _ip; }uint16_t Port() { return _port; };std::string PrintDebug(){std::string info = _ip;info += ":";info += std::to_string(_port); // "127.0.0.1:4444"return info;}~InetAddr() {}private:std::string _ip;uint16_t _port;struct sockaddr_in _addr;
};

Comm.hpp

#pragma onceenum 
{Usage_Err = 1,Socket_Err,Bind_Err
};
  • 云服务器不允许直接bind公有IP,我们也不推荐编写服务器的时候,bind明确的IP,推荐直接写成INADDR_ANY。
/* Address to accept any incoming messages. */#define INADDR_ANY ((in_addr_t) 0x00000000)

在网络编程中,当一个进程需要绑定一个网络端口以进行通信时,可以使用INADDR_ANY作为IP地址参数。这样做意味着该端口可以接受来自任何IP地址的连接请求,无论是本地主机还是远程主机。例如,如果服务器有多个网卡(每个网卡上有不同的IP地址),使用INADDR_ANY可以省去确定数据是从服务器上具体哪个网卡/IP地址上面获取的。

UdpClient.hpp

#include <iostream>
#include <cerrno>
#include <cstring>
#include <string>
#include <unistd.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>void Usage(const std::string& process)
{std::cout << "Usage: " << process << " server_ip server_port"<< std::endl;
}// ./udp_client server_ip server_port
int main(int argc, char* argv[])
{if (argc != 3){Usage(argv[0]);return 1;}std::string serverip = argv[1];uint16_t serverport = std::stoi(argv[2]);// 1. 创建 socketint sock = socket(AF_INET, SOCK_DGRAM, 0);if (sock < 0){std::cerr << "socket error: " << strerror(errno) <<std::endl;return 2;}std::cout << "create socket success: " << sock << std::endl;// 2. client 要不要进行 bind? 一定要 bind 的!!// 但是,不需要显示 bind,client 会在首次发送数据的时候会自动进行bind// 为什么?server 端的端口号,一定是众所周知,不可改变的,client 需要 port,bind 随机端口.// 为什么?client 会非常多.// client 需要 bind,但是不需要显示 bind,让本地 OS 自动随机 bind,选择随机端口号// 2.1 填充一下 server 信息struct sockaddr_in server;memset(&server, 0, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverport);server.sin_addr.s_addr = inet_addr(serverip.c_str());while (true){// 我们要发的数据std::string inbuffer;std::cout << "Please Enter# ";std::getline(std::cin, inbuffer);// 我们要发给谁呀?serverssize_t n = sendto(sock, inbuffer.c_str(),inbuffer.size(), 0, (struct sockaddr*)&server, sizeof(server));if (n > 0){char buffer[1024];//收消息struct sockaddr_in temp;socklen_t len = sizeof(temp);ssize_t m = recvfrom(sock, buffer, sizeof(buffer) - 1,0, (struct sockaddr*)&temp, &len); // 一般建议都是要填的.if (m > 0){buffer[m] = 0;std::cout << "server echo# " << buffer <<std::endl;}elsebreak;}elsebreak;}close(sock);return 0;
}

1.2 -> V2版本 -DictServer

实现一个简单的英译汉的网络字典

dict.txt

apple:苹果
banana:香蕉
cat:猫
dog:狗
book:书
pen:笔
happy:快乐的
sad:悲伤的
run:跑
jump:跳
teacher:老师
student:学生
car:汽车
bus:公交车
love:爱
hate:恨
hello:你好
goodbye:再见
summer:夏天
winter:冬天

Dict.hpp

#pragma once
#include <iostream>
#include <string>
#include <fstream>
#include <unordered_map>const std::string sep = ": ";class Dict
{
private:void LoadDict(){std::ifstream in(_confpath);if (!in.is_open()){std::cerr << "open file error" << std::endl; // 后面可以用日志替代打印return;}std::string line;while (std::getline(in, line)){if (line.empty()) continue;auto pos = line.find(sep);if (pos == std::string::npos) continue;std::string key = line.substr(0, pos);std::string value = line.substr(pos + sep.size());_dict.insert(std::make_pair(key, value));}in.close();}public:Dict(const std::string& confpath) :_confpath(confpath){LoadDict();}std::string Translate(const std::string& key){auto iter = _dict.find(key);if (iter == _dict.end()) return std::string("Unknown");else return iter->second;}~Dict(){}private:std::string _confpath;std::unordered_map<std::string, std::string> _dict;
};

UdpServer.hpp

#pragma once
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unordered_map>
#include <functional>
#include "nocopy.hpp"
#include "Log.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"const static uint16_t defaultport = 8888;
const static int defaultfd = -1;
const static int defaultsize = 1024;using func_t = std::function<void(const std::string& req,std::string* resp)>;class UdpServer : public nocopy
{
public:UdpServer(func_t func, uint16_t port = defaultport): _func(func), _port(port), _sockfd(defaultfd){}void Init(){// 1. 创建 socket,就是创建了文件细节_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd < 0){lg.LogMessage(Fatal, "socket errr, %d : %s\n", errno,strerror(errno));exit(Socket_Err);}lg.LogMessage(Info, "socket success, sockfd: %d\n",_sockfd);// 2. 绑定,指定网络信息struct sockaddr_in local;bzero(&local, sizeof(local)); // memsetlocal.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = INADDR_ANY; // 0// local.sin_addr.s_addr = inet_addr(_ip.c_str()); // 1. 4字节 IP 2. 变成网络序列// 结构体填完,设置到内核中了吗??没有int n = ::bind(_sockfd, (struct sockaddr*)&local,sizeof(local));if (n != 0){lg.LogMessage(Fatal, "bind errr, %d : %s\n", errno,strerror(errno));exit(Bind_Err);}}void Start(){// 服务器永远不退出char buffer[defaultsize];for (;;){struct sockaddr_in peer;socklen_t len = sizeof(peer); // 不能乱写ssize_t n = recvfrom(_sockfd, buffer, sizeof(buffer) -1, 0, (struct sockaddr*)&peer, &len);if (n > 0){InetAddr addr(peer);buffer[n] = 0;std::cout << "[" << addr.PrintDebug() << "]# " <<buffer << std::endl;std::string value;_func(buffer, &value); // 回调业务翻译方法sendto(_sockfd, value.c_str(), value.size(), 0,(struct sockaddr*)&peer, len);}}}~UdpServer(){}private:// std::string _ip; // 后面要调整uint16_t _port;int _sockfd;func_t _func;
};

Main.cc

#include "UdpServer.hpp"
#include "Comm.hpp"
#include "Dict.hpp"
#include <memory>void Usage(std::string proc)
{std::cout << "Usage : \n\t" << proc << " local_port\n" <<std::endl;
}Dict gdict("./dict.txt");
void Execute(const std::string& req, std::string* resp)
{*resp = gdict.Translate(req);
}// ./udp_server 8888
int main(int argc, char* argv[])
{if (argc != 2){Usage(argv[0]);return Usage_Err;}// std::string ip = argv[1];uint16_t port = std::stoi(argv[1]);std::unique_ptr<UdpServer> usvr =std::make_unique<UdpServer>(Execute, port);usvr->Init();usvr->Start();return 0;
}

1.3 -> V2版本 -DictServer(封装版)

udp_socket.hpp

#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cassert>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;class UdpSocket 
{
public:UdpSocket() : fd_(-1) {}bool Socket() {fd_ = socket(AF_INET, SOCK_DGRAM, 0);if (fd_ < 0) {perror("socket");return false;}return true;}bool Close() {close(fd_);return true;}bool Bind(const std::string& ip, uint16_t port) {sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip.c_str());addr.sin_port = htons(port);int ret = bind(fd_, (sockaddr*)&addr, sizeof(addr));if (ret < 0) {perror("bind");return false;}return true;}bool RecvFrom(std::string* buf, std::string* ip = NULL,uint16_t* port = NULL) {char tmp[1024 * 10] = { 0 };sockaddr_in peer;socklen_t len = sizeof(peer);ssize_t read_size = recvfrom(fd_, tmp,sizeof(tmp) - 1, 0,(sockaddr*)&peer, &len);if (read_size < 0) {perror("recvfrom");return false;}// 将读到的缓冲区内容放到输出参数中buf->assign(tmp, read_size);if (ip != NULL) {*ip = inet_ntoa(peer.sin_addr);}if (port != NULL) {*port = ntohs(peer.sin_port);}return true;}bool SendTo(const std::string& buf, const std::string& ip,uint16_t port) {sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip.c_str());addr.sin_port = htons(port);ssize_t write_size = sendto(fd_, buf.data(), buf.size(), 0,(sockaddr*)&addr, sizeof(addr));if (write_size < 0) {perror("sendto");return false;}return true;}private:int fd_;
};

UDP通用服务器

udp_server.hpp

#pragma once
#include "udp_socket.hpp"// C 式写法
// typedef void (*Handler)(const std::string& req, std::string*resp);
// C++ 11 式写法, 能够兼容函数指针, 仿函数, 和 lambda#include <functional>typedef std::function<void(const std::string&, std::string*resp)> Handler;class UdpServer 
{
public:UdpServer() {assert(sock_.Socket());}~UdpServer() {sock_.Close();}bool Start(const std::string& ip, uint16_t port, Handlerhandler) {// 1. 创建 socket// 2. 绑定端口号bool ret = sock_.Bind(ip, port);if (!ret) {return false;}// 3. 进入事件循环for (;;) {// 4. 尝试读取请求std::string req;std::string remote_ip;uint16_t remote_port = 0;bool ret = sock_.RecvFrom(&req, &remote_ip, &remote_port);if (!ret) {continue;}std::string resp;// 5. 根据请求计算响应handler(req, &resp);// 6. 返回响应给客户端sock_.SendTo(resp, remote_ip, remote_port);printf("[%s:%d] req: %s, resp: %s\n", remote_ip.c_str(),remote_port,req.c_str(), resp.c_str());}sock_.Close();return true;}private:UdpSocket sock_;
};

实现英译汉服务器

以上代码是对udp服务器进行通用接口的封装。基于以上封装,实现一个查字典的服务器就很容易了。

dict_server.cc

#include "udp_server.hpp"
#include <unordered_map>
#include <iostream>std::unordered_map<std::string, std::string> g_dict;void Translate(const std::string& req, std::string* resp) 
{auto it = g_dict.find(req);if (it == g_dict.end()) {*resp = "未查到!";return;}*resp = it->second;
}int main(int argc, char* argv[]) 
{if (argc != 3) {printf("Usage ./dict_server [ip] [port]\n");return 1;}// 1. 数据初始化g_dict.insert(std::make_pair("hello", "你好"));g_dict.insert(std::make_pair("world", "世界"));g_dict.insert(std::make_pair("c++", "最好的编程语言"));g_dict.insert(std::make_pair("bit", "特别 NB"));// 2. 启动服务器UdpServer server;server.Start(argv[1], atoi(argv[2]), Translate);return 0;
}

UDP通用客户端

udp_client.hpp

#pragma once
#include "udp_socket.hpp"class UdpClient 
{
public:UdpClient(const std::string& ip, uint16_t port) : ip_(ip),port_(port) {assert(sock_.Socket());}~UdpClient() {sock_.Close();}bool RecvFrom(std::string* buf) {return sock_.RecvFrom(buf);}bool SendTo(const std::string& buf) {return sock_.SendTo(buf, ip_, port_);}private:UdpSocket sock_;// 服务器端的 IP 和 端口号std::string ip_;uint16_t port_;
};

实现英译汉客户端

#include "udp_client.hpp"
#include <iostream>int main(int argc, char* argv[]) 
{if (argc != 3) {printf("Usage ./dict_client [ip] [port]\n");return 1;}UdpClient client(argv[1], atoi(argv[2]));for (;;) {std::string word;std::cout << "请输入您要查的单词: ";std::cin >> word;if (!std::cin) {std::cout << "Good Bye" << std::endl;break;}client.SendTo(word);std::string result;client.RecvFrom(&result);std::cout << word << " 意思是 " << result << std::endl;}return 0;
}

感谢各位大佬支持!!!

互三啦!!!

相关文章:

【在Linux世界中追寻伟大的One Piece】Socket编程UDP

目录 1 -> UDP网络编程 1.1 -> V1版本 -echo server 1.2 -> V2版本 -DictServer 1.3 -> V2版本 -DictServer(封装版) 1 -> UDP网络编程 1.1 -> V1版本 -echo server 简单的回显服务器和客户端代码。 备注&#xff1a;代码中会用到地址转换函数。 noc…...

机器学习在聚合物及其复合材料中的应用与实践

在当前的工业和科研领域&#xff0c;聚合物及其复合材料因其卓越的物理和化学性能而受到广泛关注。这些材料在航空航天、汽车制造、能源开发和生物医学等多个行业中发挥着至关重要的作用。随着材料科学的发展&#xff0c;传统的实验和理论分析方法已逐渐无法满足新材料研发的需…...

用大模型或者预训练模型对图片进行OCR

背景:使用大模型或者预训练模型(比如来自huggingface上的模型)对图片进行OCR,并将识别结果标记在图片原文的下方。 愿我们终有重逢之时,而你还记得我们曾经讨论的话题。 QQ group 868373192 QQ second group 277356808 要使用预训练模型对图片进行OCR(光学字符识别)…...

如何使用的是github提供的Azure OpenAI服务

使用的是github提供的Azure OpenAI的服务gpt-4o 说明&#xff1a;使用的是github提供的Azure OpenAI的服务&#xff0c;可以无限薅羊毛。开源地址 进入&#xff1a; 地址 进入后点击 右上角“Get API key”按钮 点击“Get developer key” 选择Beta版本“Generate new to…...

elementUI进度条el-progress不显示白色

效果图 通过设置百分比为100,动态修改进度条的宽度完成 <template><div class"myProgressBox"><div class"index">{{ index }}</div><div class"typeTitle">{{ typeTitle }}</div><div class"twoP…...

学习笔记——路由——IP组播-PIM(协议无关组播)-概述/PIM模式

八、PIM(协议无关组播) 1、前言 在单播中&#xff0c;是一对一的模型&#xff0c;路由器将IP数据包发往目标地址&#xff0c;因此&#xff0c;单播路由器不用关心发送数据包得源地址。而组播数据流量由组播产生&#xff0c;发向一组接收者&#xff0c;那们组播路由器如何这道…...

TCP 协议学习

一、引言 在当今的网络通信世界中&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是最为重要的协议之一。它为各种网络应用提供了可靠的、有序的数据传输服务&#xff0c;是互联网通信的基石。无论是网页浏览、电子邮件发送、…...

python3的基本数据类型:String(字符串)

一. 简介 本文简单学习了一下 python3中的一种数据类型&#xff1a; String&#xff08;字符串&#xff09;。 Python中的String类型是一种用于表示文本数据的数据类型。‌ 它可以包含字母、数字、符号等字符&#xff0c;用于存储文本信息。 二. python3的基本数据类型&…...

面试总结(2024/10/16)

面试总结&#xff08;2024/10/16&#xff09; 面试11.闭包2.promise3.全局数据的保存4.多模板切换&#xff0c;布局&#xff0c;系统主题颜色5.同一个搜索&#xff0c;不同的搜索条件&#xff0c;输入框不同的校验方法6.自定义一个组件&#xff0c;包括哪些属性7.多个父组件之间…...

从图像识别到聊天机器人:Facebook AI的多领域应用

随着人工智能技术的快速发展&#xff0c;Facebook已在多个领域内广泛应用AI技术&#xff0c;以提升用户体验、提高效率并推动创新。从图像识别到聊天机器人&#xff0c;Facebook的AI应用涵盖了社交媒体的方方面面&#xff0c;下面我们将深入探讨这些应用的具体实现及其对用户生…...

linux中级(NFS服务器)

NFS&#xff1a;用于在NNIX/Linux主机之间进行文件共享的协议 流程&#xff1a;首先服务端开启RPC服务&#xff0c;并开启111端口&#xff0c;服务器端启动NFS服务&#xff0c;并向RPC注册端口信息&#xff0c;客户端启动RPC&#xff0c;向服务器RPC服务请求NFS端口&#xff0…...

微软主动出击,“钓”出网络钓鱼者

微软正采取一种巧妙的策略来对抗网络钓鱼行为者&#xff0c;其手段是通过访问Azure平台创建高度仿真的蜜罐租户&#xff0c;以此作为诱饵&#xff0c;吸引网络犯罪分子进入&#xff0c;进而收集他们的相关信息。 凭借所收集的数据&#xff0c;微软能够绘制出恶意基础设施的地图…...

Xcode16 编译运行YYCache iOS18 sqlite3_finalize 闪退问题解决方案

问题原因 升级Xcode 16 之后&#xff0c;真机运行APP&#xff0c;发现会有Crash&#xff0c;崩溃堆栈线上Crash 在 YYCache 之中。如下图所示 崩溃堆栈如下&#xff1a; * thread #1, queue com.apple.main-thread, stop reason signal SIGABRTframe #0: 0x00000001d9391…...

Kafka-Windows搭建全流程(环境,安装包,编译,消费案例,远程连接,服务自启,可视化工具)

目录 一. Kafka安装包获取 1. 官网地址 2. 百度网盘链接 二. 环境要求 1. Java 运行环境 (1) 对 java 环境变量进行配置 (2) 下载完毕之后进行解压 三. 启动Zookeeper 四. 启动Kafka (1) 修改Conf下的server.properties文件&#xff0c;修改kafka的日志文件路径 (2)…...

django模板相关配置

模板引擎配置 Django支持多种模板引擎&#xff0c;最常用的是Django自带的模板引擎和Jinja2模板引擎。模板引擎的配置主要在settings.py文件中的TEMPLATES列表中进行。 BACKEND&#xff1a;指定模板引擎。例如&#xff0c;BACKEND: django.template.backends.django.DjangoTe…...

MongoDB等保限制下的连接认证问题

目录 一、问题描述 二、解决方案 三、代码示例 四、拓展知识 一、问题描述 用户调整用户连接认证机制以满足等保要求,调整后程序连接mongodb失败。数据库日志报错如下: {"t":{"$date":"2024-10-10T14:39:07.825+08:00"},"s":&q…...

2024 睿抗机器人开发者大赛(RAICOM)-【网络安全】CTF 部分WP

文章目录 一、前言二、MICS你是黑客么循环的压缩包Goodtime 三、WEBpy 四、Crypto变异凯撒RSAcrypto3 一、前言 WP不完整&#xff0c;仅供参考&#xff01; 除WEB&#xff0c;RE&#xff0c;PWN外&#xff0c;其余附件均已打包完毕 也是一个对MISC比较友好的一个比赛~ 123网…...

idea 无法输入中文 快速解决

idea在某些情况会出现无法输入中文的情况&#xff0c;我们不去深究内部原因&#xff0c;直接上解决方案&#xff1a; 1、点击菜单help->Edit Custom VM Options 2、最后一行&#xff0c;追加&#xff1a; -Drecreate.x11.input.methodtrue 、 3、重启...

掌握ElasticSearch(五):查询和过滤器

一、查询和过滤器的区别 在 Elasticsearch 中&#xff0c;查询&#xff08;Query&#xff09;和过滤器&#xff08;Filter&#xff09;是用于检索和筛选数据的重要组成部分。它们虽然都能用来查找文档&#xff0c;但在性能和用法上有所不同。下面详细介绍查询和过滤器的概念以…...

自学[vue+SpringCloud]-012-SpringCloud工程发送邮件

文章目录 前言一、配置QQ邮箱1.1 设置1.2 获取授权码 二、服务发送邮件2.1 引入依赖包2.2 新建AlarmMessageDto2.3 增加controller代码2.4 main方法测试 总结 前言 skywalking监控通过webhook调用SpringCloud服务接口&#xff0c;接口中发送告警邮件。 一、配置QQ邮箱 1.1 设…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...