Linux网络编程:多进程 多线程_并发服务器
文章目录:
一:wrap常用函数封装
wrap.h
wrap.c
server.c
client.c
二:多进程process并发服务器
实现思路
server.c服务器
client.c客户端
三:多线程thread并发服务器
实现思路
server.c服务器
client.c客户端
一:wrap常用函数封装
wrap.h
#ifndef __WRAP_H_ #define __WRAP_H_void perr_exit(const char *s); int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr); int Bind(int fd, const struct sockaddr *sa, socklen_t salen); int Connect(int fd, const struct sockaddr *sa, socklen_t salen); int Listen(int fd, int backlog); int Socket(int family, int type, int protocol); ssize_t Read(int fd, void *ptr, size_t nbytes); ssize_t Write(int fd, const void *ptr, size_t nbytes); int Close(int fd); ssize_t Readn(int fd, void *vptr, size_t n); ssize_t Writen(int fd, const void *vptr, size_t n); ssize_t my_read(int fd, char *ptr); ssize_t Readline(int fd, void *vptr, size_t maxlen);#endifwrap.c
#include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <sys/socket.h>void perr_exit(const char *s) {perror(s);exit(-1); }int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr) {int n;again:if ((n = accept(fd, sa, salenptr)) < 0) {if ((errno == ECONNABORTED) || (errno == EINTR))goto again;elseperr_exit("accept error");}return n; }int Bind(int fd, const struct sockaddr *sa, socklen_t salen) {int n;if ((n = bind(fd, sa, salen)) < 0)perr_exit("bind error");return n; }int Connect(int fd, const struct sockaddr *sa, socklen_t salen) {int n;n = connect(fd, sa, salen);if (n < 0) {perr_exit("connect error");}return n; }int Listen(int fd, int backlog) {int n;if ((n = listen(fd, backlog)) < 0)perr_exit("listen error");return n; }int Socket(int family, int type, int protocol) {int n;if ((n = socket(family, type, protocol)) < 0)perr_exit("socket error");return n; }ssize_t Read(int fd, void *ptr, size_t nbytes) {ssize_t n;again:if ( (n = read(fd, ptr, nbytes)) == -1) {if (errno == EINTR)goto again;elsereturn -1;}return n; }ssize_t Write(int fd, const void *ptr, size_t nbytes) {ssize_t n;again:if ((n = write(fd, ptr, nbytes)) == -1) {if (errno == EINTR)goto again;elsereturn -1;}return n; }int Close(int fd) {int n;if ((n = close(fd)) == -1)perr_exit("close error");return n; }/*参三: 应该读取的字节数 读 N 个字节*/ //socket 4096 readn(cfd, buf, 4096) nleft = 4096-1500 ssize_t Readn(int fd, void *vptr, size_t n) {size_t nleft; //usigned int 剩余未读取的字节数ssize_t nread; //int 实际读到的字节数char *ptr;ptr = vptr;nleft = n; //n 未读取字节数while (nleft > 0) {if ((nread = read(fd, ptr, nleft)) < 0) {if (errno == EINTR)nread = 0;elsereturn -1;} else if (nread == 0)break;nleft -= nread; //nleft = nleft - nread ptr += nread;}return n - nleft; }ssize_t Writen(int fd, const void *vptr, size_t n) {size_t nleft;ssize_t nwritten;const char *ptr;ptr = vptr;nleft = n;while (nleft > 0) {if ( (nwritten = write(fd, ptr, nleft)) <= 0) {if (nwritten < 0 && errno == EINTR)nwritten = 0;elsereturn -1;}nleft -= nwritten;ptr += nwritten;}return n; }static ssize_t my_read(int fd, char *ptr) {static int read_cnt;static char *read_ptr;static char read_buf[100];if (read_cnt <= 0) { again:if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { //"hello\n"if (errno == EINTR)goto again;return -1;} else if (read_cnt == 0)return 0;read_ptr = read_buf;}read_cnt--;*ptr = *read_ptr++;return 1; }/*readline读一行 --- fgets*/ //传出参数 vptr ssize_t Readline(int fd, void *vptr, size_t maxlen) {ssize_t n, rc;char c, *ptr;ptr = vptr;for (n = 1; n < maxlen; n++) {if ((rc = my_read(fd, &c)) == 1) { //ptr[] = hello\n*ptr++ = c;if (c == '\n')break;} else if (rc == 0) {*ptr = 0;return n-1;} elsereturn -1;}*ptr = 0;return n; }
利用封装函数: 联合编译server.c 和 wrap.c 生成 server、 联合编译 client.c 和 wrap.c 生成 client
server.c
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <strings.h> #include <string.h> #include <ctype.h> #include <arpa/inet.h>#include "wrap.h"#define SERV_PORT 6666int main(void) {int sfd, cfd;int len, i;char buf[BUFSIZ], clie_IP[BUFSIZ];struct sockaddr_in serv_addr, clie_addr;socklen_t clie_addr_len;sfd = Socket(AF_INET, SOCK_STREAM, 0);int opt = 1;setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); Bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));Listen(sfd, 2); printf("wait for client connect ...\n");clie_addr_len = sizeof(clie_addr_len);cfd = Accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len);printf("cfd = ----%d\n", cfd);printf("client IP: %s port:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port));while (1) {len = Read(cfd, buf, sizeof(buf));Write(STDOUT_FILENO, buf, len);for (i = 0; i < len; i++)buf[i] = toupper(buf[i]);Write(cfd, buf, len); }Close(sfd);Close(cfd);return 0; }client.c
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h>#include "wrap.h"#define SERV_IP "127.0.0.1" #define SERV_PORT 6666int main(void) {int sfd, len;struct sockaddr_in serv_addr;char buf[BUFSIZ]; sfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr); serv_addr.sin_port = htons(SERV_PORT); Connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));while (1) {fgets(buf, sizeof(buf), stdin);int r = Write(sfd, buf, strlen(buf)); printf("Write r ======== %d\n", r);len = Read(sfd, buf, sizeof(buf));printf("Read len ========= %d\n", len);Write(STDOUT_FILENO, buf, len);}Close(sfd);return 0; }
read 函数的返回值
read 函数的返回值:1. > 0 实际读到的字节数2. = 0 已经读到结尾(对端已经关闭)【 !重 !点 !】3. -1 应进一步判断errno的值:errno = EAGAIN or EWOULDBLOCK: 设置了非阻塞方式 读。 没有数据到达。 errno = EINTR 慢速系统调用被 中断。errno = “其他情况” 异常。
二:多进程process并发服务器
使用多进程并发服务器时要考虑以下几点:1.父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)2.系统内创建进程个数(与内存大小相关)3.进程创建过多是否降低整体服务性能(进程调度)实现思路
1. Socket(); 创建 监听套接字 lfd2. Bind() 绑定地址结构 Strcut scokaddr_in addr;3. Listen(); 4. while (1) {cfd = Accpet(); 接收客户端连接请求。pid = fork();if (pid == 0){ 子进程 read(cfd) --- 小-》大 --- write(cfd)close(lfd) 关闭用于建立连接的套接字 lfdread()小--大write()} else if (pid > 0) { close(cfd); 关闭用于与客户端通信的套接字 cfd contiue;}}5. 子进程:close(lfd)read()小--大write() 父进程:close(cfd);注册信号捕捉函数: SIGCHLD在回调函数中, 完成子进程回收while (waitpid());
server.c服务器
#include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #include <sys/wait.h> #include <ctype.h> #include <unistd.h>#include "wrap.h"#define MAXLINE 8192 #define SERV_PORT 8000void do_sigchild(int num) {while (waitpid(0, NULL, WNOHANG) > 0); }int main(void) {struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int i, n;pid_t pid;struct sigaction newact;newact.sa_handler = do_sigchild;sigemptyset(&newact.sa_mask);newact.sa_flags = 0;sigaction(SIGCHLD, &newact, NULL);listenfd = Socket(AF_INET, SOCK_STREAM, 0);int opt = 1;setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));Listen(listenfd, 20);printf("Accepting connections ...\n");while (1) {cliaddr_len = sizeof(cliaddr);connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);printf("-------------------------%d\n", connfd);pid = fork();if (pid == 0) {Close(listenfd);while (1) {n = Read(connfd, buf, MAXLINE);if (n == 0) {printf("the other side has been closed.\n");break;}printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));for (i = 0; i < n; i++)buf[i] = toupper(buf[i]);Write(STDOUT_FILENO, buf, n);Write(connfd, buf, n);}Close(connfd);return 0;} else if (pid > 0) {Close(connfd);} elseperr_exit("fork");}return 0; }client.c客户端
/* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h>#include "wrap.h"#define MAXLINE 8192 #define SERV_PORT 8000int main(int argc, char *argv[]) {struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, n;sockfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (fgets(buf, MAXLINE, stdin) != NULL) {Write(sockfd, buf, strlen(buf));n = Read(sockfd, buf, MAXLINE);if (n == 0) {printf("the other side has been closed.\n");break;}elseWrite(STDOUT_FILENO, buf, n);}Close(sockfd);return 0; }
三:多线程thread并发服务器
在使用线程模型开发服务器时需考虑以下问题:1.调整进程内最大文件描述符上限2.线程如有共享数据,考虑线程同步3.服务于客户端线程退出时,退出处理。(退出值,分离态)4.系统负载,随着链接客户端增加,导致其它线程不能及时得到CPU实现思路
1. Socket(); 创建 监听套接字 lfd2. Bind() 绑定地址结构 Strcut scokaddr_in addr;3. Listen(); 4. while (1) { cfd = Accept(lfd, );pthread_create(&tid, NULL, tfn, (void *)cfd);pthread_detach(tid); // pthead_join(tid, void **); 新线程---专用于回收子线程}5. 子线程:void *tfn(void *arg) {// close(lfd) 不能关闭。 主线程要使用lfdread(cfd)小--大write(cfd)pthread_exit((void *)10); }
server.c服务器
#include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> #include <ctype.h> #include <unistd.h> #include <fcntl.h>#include "wrap.h"#define MAXLINE 8192 #define SERV_PORT 8000struct s_info { //定义一个结构体, 将地址结构跟cfd捆绑struct sockaddr_in cliaddr;int connfd; };void *do_work(void *arg) {int n,i;struct s_info *ts = (struct s_info*)arg;char buf[MAXLINE];char str[INET_ADDRSTRLEN]; //#define INET_ADDRSTRLEN 16 可用"[+d"查看while (1) {n = Read(ts->connfd, buf, MAXLINE); //读客户端if (n == 0) {printf("the client %d closed...\n", ts->connfd);break; //跳出循环,关闭cfd}printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),ntohs((*ts).cliaddr.sin_port)); //打印客户端信息(IP/PORT)for (i = 0; i < n; i++) buf[i] = toupper(buf[i]); //小写-->大写Write(STDOUT_FILENO, buf, n); //写出至屏幕Write(ts->connfd, buf, n); //回写给客户端}Close(ts->connfd);return (void *)0; }int main(void) {struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;pthread_t tid;struct s_info ts[256]; //创建结构体数组.int i = 0;listenfd = Socket(AF_INET, SOCK_STREAM, 0); //创建一个socket, 得到lfdbzero(&servaddr, sizeof(servaddr)); //地址结构清零servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //指定本地任意IPservaddr.sin_port = htons(SERV_PORT); //指定端口号 Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); //绑定Listen(listenfd, 128); //设置同一时刻链接服务器上限数printf("Accepting client connect ...\n");while (1) {cliaddr_len = sizeof(cliaddr);connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); //阻塞监听客户端链接请求ts[i].cliaddr = cliaddr;ts[i].connfd = connfd;pthread_create(&tid, NULL, do_work, (void*)&ts[i]);pthread_detach(tid); //子线程分离,防止僵线程产生.i++;}return 0; }client.c客户端
/* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include "wrap.h"#define MAXLINE 80 #define SERV_PORT 8000int main(int argc, char *argv[]) {struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, n;sockfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr.s_addr);servaddr.sin_port = htons(SERV_PORT);Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (fgets(buf, MAXLINE, stdin) != NULL) {Write(sockfd, buf, strlen(buf));n = Read(sockfd, buf, MAXLINE);if (n == 0)printf("the other side has been closed.\n");elseWrite(STDOUT_FILENO, buf, n);}Close(sockfd);return 0; }
相关文章:
Linux网络编程:多进程 多线程_并发服务器
文章目录: 一:wrap常用函数封装 wrap.h wrap.c server.c client.c 二:多进程process并发服务器 实现思路 server.c服务器 client.c客户端 三:多线程thread并发服务器 实现思路 server.c服务器 client.c客户端 一&am…...
解决:(error) ERR unknown command shutdow,with args beginning with
目录 一、遇到问题 二、出现问题的原因 三、解决办法 一、遇到问题 要解决连接redis闪退的问题,按照许多的方式去进行都没有成功,在尝试使用了以下的命名去尝试时候,发现了这个问题。 二、出现问题的原因 这是一个粗心大意导致的错误&am…...
《TCP IP网络编程》第十八章
第 18 章 多线程服务器端的实现 18.1 理解线程的概念 线程背景: 第 10 章介绍了多进程服务端的实现方法。多进程模型与 select 和 epoll 相比的确有自身的优点,但同时也有问题。如前所述,创建(复制)进程的工作本身会…...
TCP编程流程
目录 1、主机字节序列和网络字节序列 2、套接字地址结构 3、IP地址转换函数 4、TCP协议编程: (1)服务器端: (2)客户端: 1、主机字节序列和网络字节序列 主机字节序列分为大端字节序和小端字节序 大端…...
CSDN编程题-每日一练(2023-08-19)
CSDN编程题-每日一练(2023-08-19) 一、题目名称:风险投资二、题目名称:幼稚班作业三、题目名称:韩信点兵一、题目名称:风险投资 时间限制:1000ms内存限制:256M 题目描述: 风险投资是一种感性和理性并存的投资方式,风险投资人一般会对请公允的第三方评估公司对投资对象…...
03_缓存双写一致性
03——缓存双写一致性 一、缓存双写一致性 如果redis中有数据,需要和数据库中的值相同如果redis中无数据,数据库中的值要是最新值,且准备回写redis 缓存按照操作来分,可以分为两种: 只读缓存 读写缓存 同步直写操作…...
机器学习之数据集
目录 1、简介 2、可用数据集 3、scikit-learn数据集API 3.1、小数据集 3.2、大数据集 4、数据集使用 ⭐所属专栏:人工智能 文中提到的代码如有需要可以私信我发给你😊 1、简介 当谈论数据集时,通常是指在机器学习和数据分析中使用的一组…...
PyTorch Geometric基本教程
PyG官方文档 # Install torch geometric !pip install -q torch-scatter -f https://pytorch-geometric.com/whl/torch-1.10.2cu102.html !pip install -q torch-sparse -f https://pytorch-geometric.com/whl/torch-1.10.2cu102.html !pip install -q torch-geometricimport t…...
MAC 命令行启动tomcat的详细介绍
MAC 命令行启动tomcat MAC 命令行启动tomcat的详细介绍 一、修改授权 进入tomcat的bin目录,修改授权 1 2 3 ➜ bin pwd /Users/yp/Documents/workspace/apache-tomcat-7.0.68/bin ➜ bin sudo chmod 755 *.sh sudo为系统超级管理员权限.chmod 改变一个或多个文件的存取模…...
idea2023 springboot2.7.5+mybatisplus3.5.2+jsp 初学单表增删改查
创建项目 修改pom.xml 为2.7.5 引入mybatisplus 2.1 修改pom.xml <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!--mysq…...
轻松搭建书店小程序
在现今数字化时代,拥有一个自己的小程序成为了许多企业和个人的追求。而对于书店经营者来说,拥有一个能够提供在线购书服务的小程序将有助于吸引更多的读者,并提升销售额。本文将为您介绍如何轻松搭建书店小程序,并将其成功上线。…...
Spark MLlib机器学习库(一)决策树和随机森林案例详解
Spark MLlib机器学习库(一)决策树和随机森林案例详解 1 决策树预测森林植被 1.1 Covtype数据集 数据集的下载地址: https://www.kaggle.com/datasets/uciml/forest-cover-type-dataset 该数据集记录了美国科罗拉多州不同地块的森林植被类型,每个样本…...
CI/CD入门(二)
CI/CD入门(二) 目录 CI/CD入门(二) 1、代码上线方案 1.1 早期手动部署代码1.2 合理化上线方案1.3 大型企业上线制度和流程1.4 php程序代码上线的具体方案1.5 Java程序代码上线的具体方案1.6 代码上线解决方案注意事项2、理解持续集成、持续交付、持续部署 2.1 持续集成2.2 持续…...
【BASH】回顾与知识点梳理(三十五)
【BASH】回顾与知识点梳理 三十五 三十五. 二十七至三十四章知识点总结及练习35.1 总结35.2 练习RAIDLVMsystemd 35.3 简答题 该系列目录 --> 【BASH】回顾与知识点梳理(目录) 三十五. 二十七至三十四章知识点总结及练习 35.1 总结 Quota 可公平的分…...
excel逻辑函数篇2
1、IF(logical_test,[value_if_true],[value_if_false]):判断是否满足某个条件,如果满足返回一个值,如果不满足则返回另一个值 if(条件,条件成立返回的值,条件不成立返回的值) 2、IFS(logical_test1,value_if_true1,…):检查是否…...
设计模式详解-解释器模式
类型:行为型模式 实现原理:实现了一个表达式接口,该接口使用标识来解释语言中的句子 作用:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器来解释。 主要解决:一些重…...
如何在React项目中动态插入HTML内容
React是一种流行的JavaScript库,用于构建用户界面。它提供了一种声明式的方法来创建可复用的组件,使得开发者能够更轻松地构建交互性的Web应用程序。在React中,我们通常使用JSX语法来描述组件的结构和行为。 在某些情况下,我们可…...
十六、Spring Cloud Sleuth 分布式请求链路追踪
目录 一、概述1、为什么出出现这个技术?需要解决哪些问题2、是什么?3、解决 二、搭建链路监控步骤1、下载运行zipkin2、服务提供者3、服务调用者4、测试 一、概述 1、为什么出出现这个技术?需要解决哪些问题 2、是什么? 官网&am…...
ElasticSearch DSL语句(bool查询、算分控制、地理查询、排序、分页、高亮等)
文章目录 DSL 查询种类DSL query 基本语法1、全文检索2、精确查询3、地理查询4、function score (算分控制)5、bool 查询 搜索结果处理1、排序2、分页3、高亮 RestClient操作 DSL 查询种类 查询所有:查询所有数据,一般在测试时使…...
【考研数学】概率论与数理统计 | 第一章——随机事件与概率(2,概率基本公式与事件独立)
文章目录 引言四、概率基本公式4.1 减法公式4.2 加法公式4.3 条件概率公式4.4 乘法公式 五、事件的独立性5.1 事件独立的定义5.1.1 两个事件的独立5.1.2 三个事件的独立 5.2 事件独立的性质 写在最后 引言 承接上文,继续介绍概率论与数理统计第一章的内容。 四、概…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
