【Linux】基于UDP/TCP服务器与客户端的实现

目录

一、UDP

(一)Server.hpp

(二)Server.cpp

(三)Client.hpp

(四)Client.cpp

(五)User.hpp

二、TCP

(一)多进程版本的服务器与客户端

1、Server.hpp

2、Server.cpp

3、Client.hpp

4、Client.cpp

5、log.hpp

(二)多线程版本的服务器与客户端

(三)线程池版本的服务器与客户端

1、Server.hpp

2、thread.hpp

3、pthreadpool.hpp

4、Task.hpp

(四)线程池版本+守护进程的服务器与客户端

1、daemon.hpp

2、Server.cpp


一、UDP

(一)Server.hpp

#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
using namespace std;
class Server
{typedef function<void(int, string, uint16_t, string)> func_t;public:Server(const func_t func, const uint16_t &port, const string &ip = "0.0.0.0") : _func(func), _port(port), _ip(ip) {}void init(){_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket :" << strerror(errno) << endl;exit(1);}cerr << "socket succcess" << endl;struct sockaddr_in addr;bzero(&addr, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(_port);addr.sin_addr.s_addr = inet_addr(_ip.c_str());int n = bind(_fd, (const sockaddr *)&addr, sizeof(addr));if (n != 0){cerr << "bind error : " << strerror(errno) << endl;exit(2);}cerr << "bind success" << endl;}void start(){char buffer[1024];while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);size_t n = recvfrom(_fd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&addr, &len);if (n > 0){buffer[n] = 0;uint16_t port = ntohs(addr.sin_port);string ip = inet_ntoa(addr.sin_addr);string messages = buffer;_func(_fd, ip, port, messages);}}}private:func_t _func;int _fd;uint16_t _port;string _ip;
};

(二)Server.cpp

#include "Server.hpp"
#include "User.hpp"
#include <memory>userManager m;
void handlerMessage(int sockfd, const string &ip, const uint16_t &port, const string &message)
{cout << "[" + ip + "]" + "[" + to_string(port) + "]: " + message << endl;if (message == "online")m.insert(ip, port);else if (message == "offline")m.erase(ip, port);else if (m.isOnline(ip, port))m.broadcast(sockfd, ip, port, message);else{struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(ip.c_str());addr.sin_port = htons(port);string response = "请先输入 online 上线";sendto(sockfd, response.c_str(), response.size(), 0, (struct sockaddr *)&addr, sizeof(addr));}
}
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(3);}uint16_t port = atoi(argv[1]);unique_ptr<Server> usvr(new Server(handlerMessage, port));usvr->init();usvr->start();return 0;
}

(三)Client.hpp

#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>using namespace std;
class Client
{
public:Client(const uint16_t &Sport, const string &Sip) : _Sport(Sport), _Sip(Sip) {}void init(){_fd = socket(AF_INET, SOCK_DGRAM, 0);if (_fd == -1){cerr << "socket : " << strerror(errno) << endl;exit(1);}cout << "socket success" << endl;}static void *readMessage(void *arg){int sockfd = *(static_cast<int *>(arg));while (true){char buffer[1024];struct sockaddr_in temp;socklen_t temp_len = sizeof(temp);size_t n = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&temp, &temp_len);if (n >= 0)buffer[n] = 0;cout << buffer << endl;}return nullptr;}void run(){pthread_create(&_read, nullptr, readMessage, (void *)&_fd);pthread_detach(_read);struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(_Sport);addr.sin_addr.s_addr = inet_addr(_Sip.c_str());socklen_t len = sizeof(addr);while (1){cerr << "Please input" << endl;string messages;cin >> messages;sendto(_fd, messages.c_str(), messages.size(), 0, (struct sockaddr *)&addr, sizeof(addr));}}private:int _fd;uint16_t _Sport;string _Sip;pthread_t _read;
};

(四)Client.cpp

#include "Client.hpp"
#include <memory>
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);exit(3);}string ip = argv[1];uint16_t port = atoi(argv[2]);unique_ptr<Client> ucli(new Client(port, ip));ucli->init();ucli->run();return 0;
}

(五)User.hpp

#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>using namespace std;
class user
{
public:user(const string &ip, const uint16_t &port) : _ip(ip), _port(port) {}string &getIp(){return _ip;}uint16_t &getPort(){return _port;}private:string _ip;uint16_t _port;
};class userManager
{
public:void insert(const string &ip, const uint16_t &port){string id = ip + "-" + to_string(port);_um.insert(make_pair(id, user(ip, port)));}void erase(const string &ip, const uint16_t &port){string id = ip + "-" + to_string(port);_um.erase(id);}bool isOnline(const string &ip, const uint16_t &port){string id = ip + "-" + to_string(port);return _um.find(id) == _um.end() ? false : true;}void broadcast(int sockfd, const string &ip, const uint16_t &port, const string &message){for (auto &user : _um){struct sockaddr_in addr;bzero(&addr, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(user.second.getPort());addr.sin_addr.s_addr = inet_addr(user.second.getIp().c_str());string response = "[" + ip + "]" + "[" + to_string(port) + "]: " + message;sendto(sockfd, response.c_str(), response.size(), 0, (sockaddr *)&addr, sizeof(addr));}}private:unordered_map<string, user> _um;
};

二、TCP

(一)多进程版本的服务器与客户端

1、Server.hpp

#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <pthread.h>
#include "log.hpp"
using namespace std;
class Server
{
public:Server(const uint16_t &port) : _fd(-1), _port(port) {}void init(){_fd = socket(AF_INET, SOCK_STREAM, 0);if (_fd == -1){cerr << strerror(errno) << endl;exit(1);}logMessage(NORMAL, "socket success");struct sockaddr_in addr;bzero(&addr, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(_port);int n = bind(_fd, (struct sockaddr *)&addr, sizeof(addr));if (n == -1){logMessage(ERROR, strerror(errno));exit(2);}logMessage(NORMAL, "bind success");n = listen(_fd, 5);if (n < 0){cerr << strerror(errno) << endl;exit(2);}logMessage(NORMAL, "listen success");}// 进程版void start(){signal(SIGCHLD, SIG_IGN);while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);int socket = accept(_fd, (struct sockaddr *)&addr, &len);cout << "accept successs : " << socket << endl;if (socket == -1){cerr << strerror(errno) << endl;continue;}pid_t id = fork();if (id == 0){close(_fd);serviceIO(socket);close(socket);exit(0);}close(socket);}}void serviceIO(const int &fd){while (1){char buffer[1024];ssize_t size = read(fd, buffer, sizeof(buffer) - 1);if (size > 0){buffer[size] = 0;cout << "[Client] : " << buffer << endl;string messages = buffer;ssize_t ret = write(fd, messages.c_str(), messages.size());if (ret < 0){cerr << strerror(errno) << endl;}}else if (size == 0){cerr << "Client quit" << endl;break;}else{cerr << strerror(errno) << endl;exit(3);}}}void start(){while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);int socket = accept(_fd, (struct sockaddr *)&addr, &len);if (socket == -1){cerr << strerror(errno) << endl;continue;}logMessage(NORMAL, "accept successs : %d", socket);}}~Server(){close(_fd);}private:int _fd;uint16_t _port;
};

2、Server.cpp

#include "Server.hpp"
#include "daemon.hpp"
#include <memory>
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(3);}uint16_t port = atoi(argv[1]);unique_ptr<Server> usvr(new Server(port));usvr->init();usvr->start();return 0;
}

3、Client.hpp

#include <iostream>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "log.hpp"
using namespace std;
class Client
{
public:Client(const string &ip, const uint16_t &port) : _fd(-1), _Sip(ip), _Sport(port) {}void init(){_fd = socket(AF_INET, SOCK_STREAM, 0);if (_fd == -1){cerr << strerror(errno) << endl;exit(1);}logMessage(NORMAL, "socket success");}void run(){struct sockaddr_in addr;bzero(&addr, 0);addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr(_Sip.c_str());addr.sin_port = htons(_Sport);if (connect(_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1){cerr << strerror(errno) << endl;exit(2);}else{while (true){string messages;cout << " please input#";getline(cin, messages);write(_fd, messages.c_str(), messages.size());char buffer[1024];int n = read(_fd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = 0;cout << "[Server] : " << buffer << endl;}elsebreak;}}}~Client(){close(_fd);}private:int _fd;string _Sip;uint16_t _Sport;
};

4、Client.cpp

#include "Client.hpp"
#include <memory>
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);exit(3);}string ip = argv[1];uint16_t port = atoi(argv[2]);unique_ptr<Client> ucli(new Client(ip, port));ucli->init();ucli->run();return 0;
}

5、log.hpp

#pragma once
#include <iostream>
#include <ctime>
#include <stdio.h>
#include <stdarg.h>
using namespace std;
#define DEBUG 0
#define NORMAL 1
#define WARNING 2
#define ERROR 3
#define FATAL 4
#define NUM 1024
const char *getLevel(const int &level)
{switch (level){case 0:return "DEBUG";case 1:return "NORMAL";case 2:return "WARNING";case 3:return "ERROR";case 4:return "FATAL";default:return nullptr;}
}
void logMessage(int level, const char *format, ...)
{char logprefix[NUM];sprintf(logprefix, "[%s][%ld]:", getLevel(level), time(nullptr));char logContext[NUM];va_list arg;va_start(arg, format);vsnprintf(logContext, sizeof(logContext), format, arg);cout << logprefix << logContext << endl;
}

(二)多线程版本的服务器与客户端

        多线程版本只有Server.hpp与多进程不同,其他文件相同。

#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <pthread.h>
#include "log.hpp"
using namespace std;
class Server
{
public:Server(const uint16_t &port) : _fd(-1), _port(port) {}void init(){_fd = socket(AF_INET, SOCK_STREAM, 0);if (_fd == -1){cerr << strerror(errno) << endl;exit(1);}logMessage(NORMAL, "socket success");struct sockaddr_in addr;bzero(&addr, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(_port);int n = bind(_fd, (struct sockaddr *)&addr, sizeof(addr));if (n == -1){logMessage(ERROR, strerror(errno));exit(2);}logMessage(NORMAL, "bind success");n = listen(_fd, 5);if (n < 0){cerr << strerror(errno) << endl;exit(2);}logMessage(NORMAL, "listen success");}// 线程版void start(){while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);int socket = accept(_fd, (struct sockaddr *)&addr, &len);cout << "accept successs : " << socket << endl;if (socket == -1){cerr << strerror(errno) << endl;continue;}pthread_t t;pthread_create(&t, nullptr, serviceIO, (void *)&socket);pthread_detach(t);}}static void *serviceIO(void *arg){int fd = *(static_cast<int *>(arg));while (1){char buffer[1024];ssize_t size = read(fd, buffer, sizeof(buffer) - 1);if (size > 0){buffer[size] = 0;cout << "[Client] : " << buffer << endl;string messages = buffer;ssize_t ret = write(fd, messages.c_str(), messages.size());if (ret < 0){cerr << strerror(errno) << endl;}}else if (size == 0){cerr << "Client quit" << endl;break;}else{cerr << strerror(errno) << endl;exit(3);}}close(fd);return nullptr;}void start(){while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);int socket = accept(_fd, (struct sockaddr *)&addr, &len);if (socket == -1){cerr << strerror(errno) << endl;continue;}logMessage(NORMAL, "accept successs : %d", socket);}}~Server(){close(_fd);}private:int _fd;uint16_t _port;
};

(三)线程池版本的服务器与客户端

        其他文件与多进程版本相同。

1、Server.hpp

#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <pthread.h>
#include "pthreadpool.hpp"
#include "Task.hpp"
#include "log.hpp"
using namespace std;
class Server
{
public:Server(const uint16_t &port) : _fd(-1), _port(port) {}void init(){_fd = socket(AF_INET, SOCK_STREAM, 0);if (_fd == -1){cerr << strerror(errno) << endl;exit(1);}logMessage(NORMAL, "socket success");struct sockaddr_in addr;bzero(&addr, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(_port);int n = bind(_fd, (struct sockaddr *)&addr, sizeof(addr));if (n == -1){logMessage(ERROR, strerror(errno));exit(2);}logMessage(NORMAL, "bind success");n = listen(_fd, 5);if (n < 0){cerr << strerror(errno) << endl;exit(2);}logMessage(NORMAL, "listen success");}void start(){pthreadPool<Task>::getInstance()->run();while (1){struct sockaddr_in addr;socklen_t len = sizeof(addr);int socket = accept(_fd, (struct sockaddr *)&addr, &len);if (socket == -1){cerr << strerror(errno) << endl;continue;}logMessage(NORMAL, "accept successs : %d", socket);pthreadPool<Task>::getInstance()->push(Task(socket, serviceIO));}}~Server(){close(_fd);}private:int _fd;uint16_t _port;
};

2、thread.hpp

#include <iostream>
#include <pthread.h>
#include <functional>
#include <string>
using namespace std;
class Thread
{typedef std::function<void *(void *)> func_t;private:static void *start_routine(void *arg){Thread *th = static_cast<Thread *>(arg);th->callback(th->_arg);}void *callback(void *arg){return _func(arg);}public:void start(func_t func, void *arg = nullptr){_func = func;_arg = arg;pthread_create(&_tid, nullptr, start_routine, this);}void join(){pthread_join(_tid, nullptr);}~Thread(){join();}private:func_t _func;pthread_t _tid;void *_arg;
};

3、pthreadpool.hpp

#include <vector>
#include <queue>
#include "thread.hpp"
#include "Task.hpp"
template <class T>
class pthreadPool
{
private:void pop(T &date){date = _tasks.front();_tasks.pop();}static void *handlerTask(void *arg){pthreadPool *th = static_cast<pthreadPool *>(arg);while (1){pthread_mutex_lock(&(th->_mutex));while (th->_tasks.empty())pthread_cond_wait(&(th->_cond), &(th->_mutex));T task;th->pop(task);pthread_mutex_unlock(&(th->_mutex));task();}return nullptr;}public:pthreadPool(int num = 10) : _num(num){pthread_mutex_init(&_mutex, nullptr);pthread_cond_init(&_cond, nullptr);for (int i = 0; i < _num; ++i){_threads.push_back(new Thread());}}~pthreadPool(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_cond);for (int i = 0; i < _num; ++i){delete _threads[i];}}void run(){for (int i = 0; i < _num; ++i){_threads[i]->start(handlerTask, this);}}void push(const T &date){pthread_mutex_lock(&_mutex);_tasks.push(date);pthread_cond_signal(&_cond);pthread_mutex_unlock(&_mutex);}static pthreadPool<T> *getInstance(){if (_tp == nullptr){pthread_mutex_lock(&_sin);if (_tp == nullptr){_tp = new pthreadPool();}pthread_mutex_unlock(&_sin);}return _tp;}pthreadPool(const pthreadPool<T> &tp) = delete;pthreadPool<T> operator=(pthreadPool<T>) = delete;private:int _num;vector<Thread *> _threads;queue<T> _tasks;pthread_mutex_t _mutex;pthread_cond_t _cond;static pthreadPool<T> *_tp;static pthread_mutex_t _sin;
};
template <class T>
pthreadPool<T> *pthreadPool<T>::_tp = nullptr;template <class T>
pthread_mutex_t pthreadPool<T>::_sin = PTHREAD_MUTEX_INITIALIZER;

4、Task.hpp

#pragma once
#include <iostream>
#include <functional>
#include "log.hpp"
using namespace std;
void serviceIO(const int &fd)
{while (1){char buffer[1024];ssize_t size = read(fd, buffer, sizeof(buffer) - 1);if (size > 0){buffer[size] = 0;cout << "[Client] : " << buffer << endl;string messages = buffer;ssize_t ret = write(fd, messages.c_str(), messages.size());if (ret < 0){cerr << strerror(errno) << endl;}}else if (size == 0){logMessage(NORMAL, "Client quit");break;}else{cerr << strerror(errno) << endl;exit(3);}}close(fd);
}
class Task
{typedef function<void(int)> func_t;public:Task() {}Task(const int &socket, func_t func) : _fd(socket), _func(func){}void operator()(){_func(_fd);}private:int _fd;func_t _func;
};

(四)线程池版本+守护进程的服务器与客户端

        其他文件与线程池版本相同。

1、daemon.hpp

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
#define DEV "/dev/null"
void daemonSelf(const char *currPath = nullptr)
{signal(SIGPIPE, SIG_IGN);if (fork() > 0)exit(0);pid_t id = setsid();assert(id != -1);int fd = open(DEV, O_RDWR);if (fd >= 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);}else{close(0);close(1);close(2);}if (currPath)chdir(currPath);
}

2、Server.cpp

#include "Server.hpp"
#include "daemon.hpp"
#include <memory>
static void Usage(string proc)
{cout << "\nUsage:\n\t" << proc << " local_port\n\n";
}
int main(int argc, char *argv[])
{if (argc != 2){Usage(argv[0]);exit(3);}uint16_t port = atoi(argv[1]);unique_ptr<Server> usvr(new Server(port));usvr->init();daemonSelf();usvr->start();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23160.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI学习第一天-什么是AI

AI的发展可以被分为四次浪潮&#xff0c;这包括符号主义、机器学习与神经网络&#xff0c;以及深度学习。在这些发展中&#xff0c;深度学习凭借其在处理非结构化复杂数据、强大的学习能力和可解释性方面的优势备受关注。深度学习技术的应用不仅提升了AI系统的性能&#xff0c;…

计算机视觉:经典数据格式(VOC、YOLO、COCO)解析与转换(附代码)

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络(附代码) 第五章&#xff1…

解决本地模拟IP的DHCP冲突问题

解决 DHCP 冲突导致的多 IP 绑定失效问题 前言 续接上一篇在本机上模拟IP地址。 在实际操作中&#xff0c;如果本机原有 IP&#xff08;如 192.168.2.7&#xff09;是通过 DHCP 自动获取的&#xff0c;直接添加新 IP&#xff08;如 10.0.11.11&#xff09;可能会导致 DHCP 服…

安全生产月安全知识竞赛主持稿串词

女:尊敬的各位领导、各位来宾 男:各位参赛选手、观众朋友们 合:大家好&#xff5e; 女:安全是天&#xff0c;有了这一份天&#xff0c;我们的员工就会多一份幸福&#xff0c; 我们的企业就会多一丝光彩。 男:安全是地&#xff0c;有了这一片地&#xff0c;我们的员工就多了一…

JDBC学习

背景&#xff1a;主机正在运行mysql服务 在cmd输入 mysql -u root -p 之后&#xff0c;输入密码&#xff08;我的用户名是root&#xff0c;密码是root&#xff09;&#xff0c;成功登录到mysql。 输入&#xff1a;SHOW GLOBAL VARIABLES LIKE port; 检查mysql服务的端口号 …

前端js进阶,ES6语法,包详细

进阶ES6 作用域的概念加深对js理解 let、const申明的变量&#xff0c;在花括号中会生成块作用域&#xff0c;而var就不会生成块作用域 作用域链本质上就是底层的变量查找机制 作用域链查找的规则是:优先查找当前作用域先把的变量&#xff0c;再依次逐级找父级作用域直到全局…

IDEA通过Maven使用JBLJavaToWeb插件创建Web项目

第一步&#xff1a;IDEA下载JBLJavaToWeb插件 File--->Settings--->Plugins--->Marketplace搜索: JBLJavaToWeb 第二步&#xff1a;创建普通Maven工程 第三步&#xff1a; 将普通Maven项目转换为Web项目

在VSCode中接入deepseek

注册就送14元2000万tokens。 https://cloud.siliconflow.cn/i/rnbA6i6U各种大模型 下面介绍我是如如接入vscode的 左边生成一个key&#xff0c;呆会vscode要用&#xff0c;不然401. 打开vscod&#xff0c;电脑能上网。下插件。 下好要配置 点它一下。 要配置&#xff0c;全…

Mac端homebrew安装配置

拷打了一下午o3-mini-high&#xff0c;不如这位博主的超强帖子&#xff0c;10分钟结束战斗 跟随该文章即可&#xff0c;2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次&#xff0c;点赞258次&#xff0c;收藏837次。一直觉得自己写…

安全启动(secure boot)怎么关闭_史上最全的各品牌机和组装机关闭安全启动教程

很多网友发现电脑BIOS设置中都有一个secure boot(安全启动)选项&#xff0c;而且一些预装win10或win11改Win7的教程中也有提到要把安全启动关闭&#xff0c;那么我们该怎么关闭安全启动呢&#xff1f;下面教大家各品牌机和组装机关闭安全启动教程。 secure boot该关还是开&…

C进阶 自定义类型

目录 前言 一 结构体 二 结构体的存储 三 位段 四 枚举 五 联合体 总结 前言 我们之前学习的int char double ......都是内置类型&#xff0c;但是我们今天所学习的是自定义类型&#xff0c;比如联合体&#xff0c;结构体&#xff0c;枚举 一 结构体 结构体是一…

STM32的HAL库开发---ADC采集内部温度传感器

一、STM32内部温度传感器简介 二、温度计算方法 F1系列&#xff1a; 从数据手册中可以找到V25和Avg_Slope F4、F7、H7系列只是标准值不同&#xff0c;自行查阅手册 三、实验简要 1、功能描述 通过ADC1通道16采集芯片内部温度传感器的电压&#xff0c;将电压值换算成温度后&…

【PyQt5】python可视化开发:PyQt5介绍,开发环境搭建快速入门

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Android 串口通信

引言 在iot项目中&#xff0c;Android 端总会有和硬件通信。 通信这里&#xff1a;串口通信&#xff0c;蓝牙通信或者局域网通信。 这里讲一下串口通信。 什么是串口&#xff1f; “串口”&#xff08;Serial Port&#xff09;通常是指一种用于与外部设备进行串行通信的接口。…

跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围

一 查看springboot自带的tomcat版本&#xff1a; 可直接在项目中找到Maven Dependencies中找到tomcat版本 二、查看SpringBoot内置tomcat版本的支持范围 我这边是跟据maven仓库查看的 首先跟据链接打开maven仓库&#xff1a;https://mvnrepository.com/ 然后搜索&#xff1a…

磐维数据库双中心容灾流复制集群搭建

1. 架构 磐维数据库PanWeiDB V2.0.0基于gs_sdr工具&#xff0c;在不借助额外存储介质的情况下实现跨Region的异地容灾。提供流式容灾搭建&#xff0c;容灾升主&#xff0c;计划内主备切换&#xff0c;容灾解除、容灾状态监控等功能。 2. 部署双中心磐维集群 2.1. 主集群 角色…

Spring事务原理 二

在上一篇博文《Spring事务原理 一》中&#xff0c;我们熟悉了Spring声明式事务的AOP原理&#xff0c;以及事务执行的大体流程。 本文中&#xff0c;介绍了Spring事务的核心组件、传播行为的源码实现。下一篇中&#xff0c;我们将结合案例&#xff0c;来讲解实战中有关事务的易…

【机器学习】【KMeans聚类分析实战】用户分群聚类详解——SSE、CH 指数、SC全解析,实战电信客户分群案例

1.引言 在实际数据分析中&#xff0c;聚类算法常用于客户分群、图像分割等场景。如何确定聚类数 k 是聚类分析中的关键问题之一。本文将以“用户分群”为例&#xff0c;展示如何通过 KMeans 聚类&#xff0c;利用 SSE&#xff08;误差平方和&#xff0c;也称 Inertia&#xff…

20-R 绘图 - 饼图

R 绘图 - 饼图 R 语言提供来大量的库来实现绘图功能。 饼图&#xff0c;或称饼状图&#xff0c;是一个划分为几个扇形的圆形统计图表&#xff0c;用于描述量、频率或百分比之间的相对关系。 R 语言使用 pie() 函数来实现饼图&#xff0c;语法格式如下&#xff1a; pie(x, l…

搭建 Hadoop 3.3.6 伪分布式

搭建 Hadoop 3.3.6 伪分布式 IP 192.168.157.132 初始化操作 更改yum源 # 1_1.安装Wget yum install wget# 1_2.备份CentOS-Base.repo文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo_bak# 2.下载阿里yum源配置 wget -O /etc/yum.repos.d/Cen…