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

【在Linux世界中追寻伟大的One Piece】Socket编程TCP(续)

目录

1 -> V2 -Echo Server多进程版本

2 -> V3 -Echo Server多线程版本

3 -> V3-1 -多线程远程命令执行

4 -> V4 -Echo Server线程池版本


1 -> V2 -Echo Server多进程版本

通过每个请求,创建子进程的方式来支持多连接。

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;}const struct sockaddr_in& GetAddr(){return _addr;}bool operator == (const InetAddr & addr){//other codereturn this->_ip == addr._ip && this->_port == addr._port;}~InetAddr() {}private:std::string _ip;uint16_t _port;struct sockaddr_in _addr;
};

TcpSever.hpp

#pragma once#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include "Log.hpp"
#include "nocopy.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"const static int default_backlog = 6; // TODOclass TcpServer : public nocopy
{
public:TcpServer(uint16_t port) : _port(port), _isrunning(false){}// 都是固定套路void Init(){// 1. 创建 socket, file fd, 本质是文件_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){lg.LogMessage(Fatal, "create socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Fatal);}int opt = 1;setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR |SO_REUSEPORT, &opt, sizeof(opt));lg.LogMessage(Debug, "create socket success,sockfd: % d\n", _listensock);// 2. 填充本地网络信息并 bindstruct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = htonl(INADDR_ANY);// 2.1 bindif (bind(_listensock, CONV(&local), sizeof(local)) != 0){lg.LogMessage(Fatal, "bind socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Bind_Err);}lg.LogMessage(Debug, "bind socket success, sockfd: %d\n",_listensock);// 3. 设置 socket 为监听状态,tcp 特有的if (listen(_listensock, default_backlog) != 0){lg.LogMessage(Fatal, "listen socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Listen_Err);}lg.LogMessage(Debug, "listen socket success,sockfd: % d\n", _listensock);}// Tcp 连接全双工通信的.void Service(int sockfd){char buffer[1024];// 一直进行 IOwhile (true){ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;std::cout << "client say# " << buffer <<std::endl;std::string echo_string = "server echo# ";echo_string += buffer;write(sockfd, echo_string.c_str(),echo_string.size());}else if (n == 0) // read 如果返回值是 0,表示读到了文件结尾(对端关闭了连接!){lg.LogMessage(Info, "client quit...\n");break;}else{lg.LogMessage(Error, "read socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));break;}}}void ProcessConnection(int sockfd, struct sockaddr_in& peer){// v2 多进程pid_t id = fork();if (id < 0){close(sockfd);return;}else if (id == 0){// childclose(_listensock);if (fork() > 0)exit(0);InetAddr addr(peer); // 获取 client 地址信息lg.LogMessage(Info, "process connection: %s:%d\n",addr.Ip().c_str(), addr.Port());// 孙子进程,孤儿进程,被系统领养,正常处理Service(sockfd);close(sockfd);exit(0);}else{close(sockfd);pid_t rid = waitpid(id, nullptr, 0);if (rid == id){// do nothing}}}void Start(){_isrunning = true;while (_isrunning){// 4. 获取连接struct sockaddr_in peer;socklen_t len = sizeof(peer);int sockfd = accept(_listensock, CONV(&peer), &len);if (sockfd < 0){lg.LogMessage(Warning, "accept socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));continue;}lg.LogMessage(Debug, "accept success, get n newsockfd: % d\n", sockfd);ProcessConnection(sockfd, peer);}}~TcpServer(){}private:uint16_t _port;int _listensock; // TODObool _isrunning;
};

引入InetAddr.hpp,方便后面打印消息。

2 -> V3 -Echo Server多线程版本

Thread.hpp

#pragma once#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <pthread.h>
#include "Log.hpp"
#include "nocopy.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"const static int default_backlog = 6; // TODOclass TcpServer : public nocopy
{
public:TcpServer(uint16_t port) : _port(port), _isrunning(false){}// 都是固定套路void Init(){// 1. 创建 socket, file fd, 本质是文件_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){lg.LogMessage(Fatal, "create socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Fatal);}int opt = 1;setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR |SO_REUSEPORT, &opt, sizeof(opt));lg.LogMessage(Debug, "create socket success,sockfd: % d\n", _listensock);// 2. 填充本地网络信息并 bindstruct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = htonl(INADDR_ANY);// 2.1 bindif (bind(_listensock, CONV(&local), sizeof(local)) != 0){lg.LogMessage(Fatal, "bind socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Bind_Err);}lg.LogMessage(Debug, "bind socket success, sockfd: %d\n",_listensock);// 3. 设置 socket 为监听状态,tcp 特有的if (listen(_listensock, default_backlog) != 0){lg.LogMessage(Fatal, "listen socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Listen_Err);}lg.LogMessage(Debug, "listen socket success,sockfd: % d\n", _listensock);}class ThreadData{public:ThreadData(int sockfd, struct sockaddr_in addr): _sockfd(sockfd), _addr(addr){}~ThreadData(){}public:int _sockfd;InetAddr _addr;};// Tcp 连接全双工通信的.// 新增 staticstatic void Service(ThreadData& td){char buffer[1024];// 一直进行 IOwhile (true){ssize_t n = read(td._sockfd, buffer, sizeof(buffer) -1);if (n > 0){buffer[n] = 0;std::cout << "client say# " << buffer <<std::endl;std::string echo_string = "server echo# ";echo_string += buffer;write(td._sockfd, echo_string.c_str(),echo_string.size());}else if (n == 0) // read 如果返回值是 0,表示读到了文件结尾(对端关闭了连接!){lg.LogMessage(Info, "client[%s:%d] quit...\n",td._addr.Ip().c_str(), td._addr.Port());break;}else{lg.LogMessage(Error, "read socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));break;}}}static void* threadExcute(void* args){pthread_detach(pthread_self());ThreadData* td = static_cast<ThreadData*>(args);TcpServer::Service(*td);close(td->_sockfd);delete td;return nullptr;}void ProcessConnection(int sockfd, struct sockaddr_in& peer){// v3 多线程InetAddr addr(peer);pthread_t tid;ThreadData* td = new ThreadData(sockfd, peer);pthread_create(&tid, nullptr, threadExcute, (void*)td);}void Start(){_isrunning = true;while (_isrunning){// 4. 获取连接struct sockaddr_in peer;socklen_t len = sizeof(peer);int sockfd = accept(_listensock, CONV(&peer), &len);if (sockfd < 0){lg.LogMessage(Warning, "accept socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));continue;}lg.LogMessage(Debug, "accept success, get n newsockfd: % d\n", sockfd);ProcessConnection(sockfd, peer);}}~TcpServer(){}private:uint16_t _port;int _listensock; // TODObool _isrunning;
};

使用最原始的接口,使用内部ThreadData类。

3 -> V3-1 -多线程远程命令执行

Command.hpp

  • 命令类,用来执行命令,并获取结果。
  • 这里暂停,做一个多线程的小业务。
#pragma once#include <iostream>
#include <string>
#include <set>
#include <unistd.h>class Command
{
private:
public:Command() {}Command(int sockfd) : _sockfd(sockfd){// 限定一下命令的个数和范围_safe_command.insert("ls");_safe_command.insert("pwd");_safe_command.insert("ls -l");_safe_command.insert("ll");_safe_command.insert("touch");_safe_command.insert("who");_safe_command.insert("whoami");}bool IsSafe(const std::string& command){auto iter = _safe_command.find(command);if (iter == _safe_command.end()) return false; // 要执行的命令不 set 中,不安全else return true;}std::string Execute(const std::string& command){if (!IsSafe(command)) return "unsafe";FILE* fp = popen(command.c_str(), "r");if (fp == nullptr)return std::string();char buffer[1024];std::string result;while (fgets(buffer, sizeof(buffer), fp)){result += buffer;}pclose(fp);return result;}std::string RecvCommand(){char line[1024];ssize_t n = recv(_sockfd, line, sizeof(line) - 1, 0); if (n > 0){line[n] = 0;return line;}else{return std::string();}}void SendCommand(std::string result){if (result.empty()) result = "done"; // 主要是有些命令没有结果,比如 touchsend(_sockfd, result.c_str(), result.size(), 0);}~Command(){}private:std::set<std::string> _safe_command;int _sockfd;std::string _command;
};

TcpSever.hpp

#pragma once#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <pthread.h>
#include "Log.hpp"
#include "nocopy.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"
#include "Command.hpp" // 引入命令执行const static int default_backlog = 6; // TODOclass TcpServer : public nocopy
{
public:TcpServer(uint16_t port) : _port(port), _isrunning(false){}// 都是固定套路void Init(){// 1. 创建 socket, file fd, 本质是文件_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){lg.LogMessage(Fatal, "create socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Fatal);}int opt = 1;setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR |SO_REUSEPORT, &opt, sizeof(opt));lg.LogMessage(Debug, "create socket success,sockfd: % d\n", _listensock);// 2. 填充本地网络信息并 bindstruct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = htonl(INADDR_ANY);// 2.1 bindif (bind(_listensock, CONV(&local), sizeof(local)) != 0){lg.LogMessage(Fatal, "bind socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Bind_Err);}lg.LogMessage(Debug, "bind socket success, sockfd: %d\n",_listensock);// 3. 设置 socket 为监听状态,tcp 特有的if (listen(_listensock, default_backlog) != 0){lg.LogMessage(Fatal, "listen socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Listen_Err);}lg.LogMessage(Debug, "listen socket success,sockfd: % d\n", _listensock);}class ThreadData{public:ThreadData(int sockfd, struct sockaddr_in addr): _sockfd(sockfd), _addr(addr){}~ThreadData(){}public:int _sockfd;InetAddr _addr;};// Tcp 连接全双工通信的.// 新增 staticstatic void Service(ThreadData& td){char buffer[1024];// 一直进行 IOwhile (true){Command command(td._sockfd);std::string commandstr = command.RecvCommand();if (commandstr.empty())return;std::string result = command.Execute(commandstr);command.SendCommand(result);}}static void* threadExcute(void* args){pthread_detach(pthread_self());ThreadData* td = static_cast<ThreadData*>(args);TcpServer::Service(*td);close(td->_sockfd);delete td;return nullptr;}void ProcessConnection(int sockfd, struct sockaddr_in& peer){// v3 多线程InetAddr addr(peer);pthread_t tid;ThreadData* td = new ThreadData(sockfd, peer);pthread_create(&tid, nullptr, threadExcute, (void*)td);}void Start(){_isrunning = true;while (_isrunning){// 4. 获取连接struct sockaddr_in peer;socklen_t len = sizeof(peer);int sockfd = accept(_listensock, CONV(&peer), &len);if (sockfd < 0){lg.LogMessage(Warning, "accept socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));continue;}lg.LogMessage(Debug, "accept success, get n newsockfd: % d\n", sockfd);ProcessConnection(sockfd, peer);}}~TcpServer(){}private:uint16_t _port;int _listensock; // TODObool _isrunning;
};

4 -> V4 -Echo Server线程池版本

引入系统部分的线程池,进行简单的业务处理。

TcpServer.hpp

#pragma once#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <pthread.h>
#include <functional>
#include "Log.hpp"
#include "nocopy.hpp"
#include "Comm.hpp"
#include "InetAddr.hpp"
#include "ThreadPool.hpp"const static int default_backlog = 6; // TODOclass TcpServer : public nocopy
{
public:TcpServer(uint16_t port) : _port(port), _isrunning(false){}// 都是固定套路void Init(){// 1. 创建 socket, file fd, 本质是文件_listensock = socket(AF_INET, SOCK_STREAM, 0);if (_listensock < 0){lg.LogMessage(Fatal, "create socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Fatal);}int opt = 1;setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR |SO_REUSEPORT, &opt, sizeof(opt));lg.LogMessage(Debug, "create socket success,sockfd: % d\n", _listensock);// 2. 填充本地网络信息并 bind// struct sockaddr_in local;memset(&local, 0, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(_port);local.sin_addr.s_addr = htonl(INADDR_ANY);// 2.1 bindif (bind(_listensock, CONV(&local), sizeof(local)) != 0){lg.LogMessage(Fatal, "bind socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Bind_Err);}lg.LogMessage(Debug, "bind socket success, sockfd: %d\n",_listensock);// 3. 设置 socket 为监听状态,tcp 特有的if (listen(_listensock, default_backlog) != 0){lg.LogMessage(Fatal, "listen socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));exit(Listen_Err);}lg.LogMessage(Debug, "listen socket success,sockfd: % d\n", _listensock);}// Tcp 连接全双工通信的.void Service(int sockfd, InetAddr addr){char buffer[1024];// 一直进行 IOwhile (true){ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;std::cout << "client say# " << buffer <<std::endl;std::string echo_string = "server echo# ";echo_string += buffer;write(sockfd, echo_string.c_str(),echo_string.size());}else if (n == 0) // read 如果返回值是 0,表示读到了文件结尾(对端关闭了连接!){lg.LogMessage(Info, "client[%s:%d] quit...\n",addr.Ip().c_str(), addr.Port());break;}else{lg.LogMessage(Error, "read socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));break;}}}void ProcessConnection(int sockfd, struct sockaddr_in& peer){using func_t = std::function<void()>;InetAddr addr(peer);func_t func = std::bind(&TcpServer::Service, this, sockfd,addr); // 这里不能 autoThreadPool<func_t>::GetInstance()->Push(func);}void Start(){_isrunning = true;while (_isrunning){// 4. 获取连接struct sockaddr_in peer;socklen_t len = sizeof(peer);int sockfd = accept(_listensock, CONV(&peer), &len);if (sockfd < 0){lg.LogMessage(Warning, "accept socket error, errnocode: % d, error string : % s\n", errno, strerror(errno));continue;}lg.LogMessage(Debug, "accept success, get n newsockfd: % d\n", sockfd);ProcessConnection(sockfd, peer);}_isrunning = false;}~TcpServer(){}private:uint16_t _port;int _listensock; // TODObool _isrunning;
};

感谢各位大佬支持!!!

互三啦!!!

相关文章:

【在Linux世界中追寻伟大的One Piece】Socket编程TCP(续)

目录 1 -> V2 -Echo Server多进程版本 2 -> V3 -Echo Server多线程版本 3 -> V3-1 -多线程远程命令执行 4 -> V4 -Echo Server线程池版本 1 -> V2 -Echo Server多进程版本 通过每个请求&#xff0c;创建子进程的方式来支持多连接。 InetAddr.hpp #pragma…...

面试高频问题:C/C++编译时内存五个分区

在面试时,C/C++编译时内存五个分区是经常问到的问题,面试官通过这个问题来考察面试者对底层的理解。在平时开发时,懂编译时内存分区,也有助于自己更好管理内存。 目录 内存分区的定义 内存分区的重要性 代码区 数据区 BSS区 堆区 栈区 静态内存分配 动态内存分配…...

阅读博士论文《功率IGBT模块健康状态监测方法研究》

IGBT的失效可以分为芯片级失效和封装级失效。其中封装级失效是IGBT模块老化的主要原因&#xff0c;是多种因素共同作用的结果。在DBC的这种结构中&#xff0c;流过芯片的负载电流通过键合线传导到 DBC上层铜箔&#xff0c;再经过端子流出模块。DBC与芯片和提供机械支撑的基板之…...

Spring ApplicationContext接口

ApplicationContext接口是Spring框架中更高级的IoC容器接口&#xff0c;扩展了BeanFactory接口&#xff0c;提供了更多的企业级功能。ApplicationContext不仅具备BeanFactory的所有功能&#xff0c;还增加了事件发布、国际化、AOP、资源加载等功能。 ApplicationContext接口的…...

[perl] 数组与哈希

数组变量以 符号开始&#xff0c;元素放在括号内 简单举例如下 #!/usr/bin/perl names ("a1", "a2", "a3");print "\$names[0] $names[0]\n"; print "size: ",scalar names,"\n";$new_names shift(names); …...

电机学习-SPWM原理及其MATLAB模型

SPWM原理及其MATLAB模型 一、SPWM原理二、基于零序分量注入的SPWM三、MATLAB模型 一、SPWM原理 SPWM其实是相电压的控制方式&#xff0c;定义三相正弦相电压的表达式&#xff1a; { V a m V m sin ⁡ ω t V b m V m sin ⁡ ( ω t − 2 3 π ) V c m V m sin ⁡ ( ω t 2…...

群控系统服务端开发模式-应用开发-腾讯云上传工厂及七牛云上传工厂开发

记住业务流程图&#xff0c;要不然不清楚自己封装的是什么东西。 一、腾讯云工厂开发 切记在根目录下要安装腾讯云OSS插件&#xff0c;具体代码如下&#xff1a; composer require qcloud/cos-sdk-v5 在根目录下extend文件夹下Upload文件夹下channel文件夹中&#xff0c;我们修…...

【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法

【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法 【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和深度迁移学习的遥感影像滑坡制图方法 文章目录 【深度学习滑坡制图|论文解读3】基于融合CNN-Transformer网络和…...

《计算机原理与系统结构》学习系列——处理器(下)

系列文章目录 目录 流水线冒险数据冒险数据相关与数据冒险寄存器先读后写旁路取数使用型冒险阻塞 控制冒险分支引发的控制冒险假设分支不发生动态分支预测双预测位动态分支预测缩短分支延迟带冒险控制的单周期流水线图 异常MIPS中的异常MIPS中的异常处理另一种异常处理机制非精…...

JDK新特性(8-21)数据类型-直接内存

目录 Jdk 新特性 JDK 8 特性 默认方法实现作用:可以使接口更加灵活&#xff0c;不破坏现有实现的情况下添加新的方法。 函数式接口 StreamAPI JDK 9 特性 JDK 10 特性 JDK 11 特性 JDK 14 特性 JDK 17 特性 JDK 21 特性 数据类型 基本数据类型和引用数据类型的区别…...

003-Kotlin界面开发之声明式编程范式

概念本源 在界面程序开发中&#xff0c;有两个非常典型的编程范式&#xff1a;命令式编程和声明式编程。命令式编程是指通过编写一系列命令来描述程序的运行逻辑&#xff0c;而声明式编程则是通过编写一系列声明来描述程序的状态。在命令式编程中&#xff0c;程序员需要关心程…...

QT pro项目工程的条件编译

QT pro项目工程的条件编译 前言 项目场景&#xff1a;项目中用到同一型号两个相机&#xff0c;同时导入两个版本有冲突&#xff0c;编译不通过&#xff0c; 故从编译就区分相机导入调用&#xff0c;使用宏区分 一、定义宏 在pro文件中定义宏&#xff1a; DEFINES USE_Cam…...

深度学习之经典网络-AlexNet详解

AlexNet 是一种经典的卷积神经网络&#xff08;CNN&#xff09;架构&#xff0c;在 2012 年的 ImageNet 大规模视觉识别挑战赛&#xff08;ILSVRC&#xff09;中表现优异&#xff0c;将 CNN 引入深度学习的新时代。AlexNet 的设计在多方面改进了卷积神经网络的架构&#xff0c;…...

部署Prometheus、Grafana、Zipkin、Kiali监控度量Istio

1. 模块简介 Prometheus 是一个开源的监控系统和时间序列数据库。Istio 使用 Prometheus 来记录指标&#xff0c;跟踪 Istio 和网格中的应用程序的健康状况。Grafana 是一个用于分析和监控的开放平台。Grafana 可以连接到各种数据源&#xff0c;并使用图形、表格、热图等将数据…...

结合 Spring Boot Native 和 Spring Boot 构建高性能服务器架构

随着云计算和微服务架构的普及&#xff0c;开发者们不断寻求提高应用性能和用户体验的解决方案。Spring Boot Native 的出现&#xff0c;利用 GraalVM 的原生映像特性&#xff0c;使得 Java 应用的启动速度和资源占用得到了显著改善。本文将深入探讨如何将前端应用使用 Spring …...

ArcGIS影像调色(三原色)三原色调整

本期主要介绍ArcGIS影像调色&#xff08;三原色&#xff09; ArcGIS影像调色&#xff08;三原色&#xff09;&#xff0c;对比度、亮度、gamma。红绿蓝三原色调整。 视频学习 ArcGIS影像调色&#xff08;三原色&#xff09;...

SQLite从入门到精通面试题及参考答案

目录 SQLite 是什么? SQLite 的优点有哪些? 轻量级与易于部署 零配置和低维护成本 良好的兼容性和跨平台性 高性能和可靠性 SQLite 的局限性有哪些? 并发处理能力有限 缺乏用户管理和权限控制功能 有限的扩展性 有限的网络支持 SQLite 和其他数据库系统(如 MyS…...

【C/C++】字符/字符串函数(0)(补充)——由ctype.h提供

零.导言 除了字符分类函数&#xff0c;字符转换函数也是一类字符/字符串函数。 C语言提供了两种字符转换函数&#xff0c;分别是 toupper &#xff0c; tolower。 一.什么是字符转换函数&#xff1f; 顾名思义&#xff0c;即转换字符的函数&#xff0c;如大写字母转小写字母&am…...

Git 的特殊配置文件

文章目录 1.前言2.Git 标准配置文件.gitignore作用格式示例 .gitattributes作用格式示例 .gitmodules作用格式示例 .gitconfig作用格式示例 3.非 Git 标准约定文件.gitkeep简介示例 .gitacls作用格式示例 参考文献 1.前言 Git 是一个强大的版本控制系统&#xff0c;它使用多个…...

数据的表现形式(1)

数据的表现形式 西文字符编码 ASCII码&#xff08;美国信息交换标准码&#xff09; 计算机内部用一个字节&#xff08;8位二进制&#xff09;&#xff0c;来存放一个7位ASCII码&#xff0c;最高位为“0”&#xff0c;共 可以表示128个不同字符 ASCII码中&#xff0c;0是48&…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...