【在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 简单的回显服务器和客户端代码。 备注:代码中会用到地址转换函数。 noc…...

机器学习在聚合物及其复合材料中的应用与实践
在当前的工业和科研领域,聚合物及其复合材料因其卓越的物理和化学性能而受到广泛关注。这些材料在航空航天、汽车制造、能源开发和生物医学等多个行业中发挥着至关重要的作用。随着材料科学的发展,传统的实验和理论分析方法已逐渐无法满足新材料研发的需…...
用大模型或者预训练模型对图片进行OCR
背景:使用大模型或者预训练模型(比如来自huggingface上的模型)对图片进行OCR,并将识别结果标记在图片原文的下方。 愿我们终有重逢之时,而你还记得我们曾经讨论的话题。 QQ group 868373192 QQ second group 277356808 要使用预训练模型对图片进行OCR(光学字符识别)…...

如何使用的是github提供的Azure OpenAI服务
使用的是github提供的Azure OpenAI的服务gpt-4o 说明:使用的是github提供的Azure OpenAI的服务,可以无限薅羊毛。开源地址 进入: 地址 进入后点击 右上角“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、前言 在单播中,是一对一的模型,路由器将IP数据包发往目标地址,因此,单播路由器不用关心发送数据包得源地址。而组播数据流量由组播产生,发向一组接收者,那们组播路由器如何这道…...
TCP 协议学习
一、引言 在当今的网络通信世界中,TCP(Transmission Control Protocol,传输控制协议)是最为重要的协议之一。它为各种网络应用提供了可靠的、有序的数据传输服务,是互联网通信的基石。无论是网页浏览、电子邮件发送、…...
python3的基本数据类型:String(字符串)
一. 简介 本文简单学习了一下 python3中的一种数据类型: String(字符串)。 Python中的String类型是一种用于表示文本数据的数据类型。 它可以包含字母、数字、符号等字符,用于存储文本信息。 二. python3的基本数据类型&…...

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

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

linux中级(NFS服务器)
NFS:用于在NNIX/Linux主机之间进行文件共享的协议 流程:首先服务端开启RPC服务,并开启111端口,服务器端启动NFS服务,并向RPC注册端口信息,客户端启动RPC,向服务器RPC服务请求NFS端口࿰…...

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

Xcode16 编译运行YYCache iOS18 sqlite3_finalize 闪退问题解决方案
问题原因 升级Xcode 16 之后,真机运行APP,发现会有Crash,崩溃堆栈线上Crash 在 YYCache 之中。如下图所示 崩溃堆栈如下: * 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文件,修改kafka的日志文件路径 (2)…...
django模板相关配置
模板引擎配置 Django支持多种模板引擎,最常用的是Django自带的模板引擎和Jinja2模板引擎。模板引擎的配置主要在settings.py文件中的TEMPLATES列表中进行。 BACKEND:指定模板引擎。例如,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不完整,仅供参考! 除WEB,RE,PWN外,其余附件均已打包完毕 也是一个对MISC比较友好的一个比赛~ 123网…...

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

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

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

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...