【网络编程开发】17.“自动云同步“项目实践

17."自动云同步"项目实践

文章目录

  • 17."自动云同步"项目实践
    • 项目简介
      • 功能需求
      • 需求分析
      • 实现步骤
    • 1.实现TCP通信
      • server.c 服务端
      • tcp.h
      • client.c 客户端
    • 函数封装
      • tcp.c
      • tcp.h
      • server.c
      • client.c
      • 编译运行
    • 2.实现文件传输
      • sever.c
      • client.c
      • tcp.c
      • tcp.h
      • Makeifle
      • 编译运行
    • 3.实现用文件名传输
      • server.c
      • client.c
      • tcp.c
      • tcp.h
      • .info
      • 文件位置
      • 编译运行

项目简介

功能需求

  1. 保持云端数据和终端数据的一致
  2. 上传和下载
  3. 实时同步
  4. 定时同步
  5. 手动同步

需求分析

  1. 文件的上传和下载
  2. 文件的大小不确定
  3. 文件的个数不确定
  4. 实时同步需要获取文件事件
  5. 定时同步需要设置定时器

实现步骤

  1. 实现TCP通信
  2. 使用TCP实现文件的上传和下载
  3. 实现整个目录下的文件的同步
  4. 实现项目框架
  5. 完成项目

1.实现TCP通信

server.c 服务端

#include "tcp.h"int main(int argc, char *argv[])
{int fd, newfd;int ret;char buf[BUFSIZ];Addr_in addr, client_addr;socklen_t addrlen = sizeof(addr);/*检查参数*/if(argc < 3){fprintf(stderr, "%s <addr><port>\n", argv[0]);exit(EXIT_FAILURE);}/*创建套接字*/if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)ErrExit("socket");/*设置通信结构体*/bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*绑定通信结构体*/if( bind(fd, (Addr *)&addr, sizeof(addr) ) )ErrExit("bind");/*监听模式*/if( listen(fd, BACKLOG) )ErrExit("listen");/*接收客户端连接*/do {newfd = accept(fd, (Addr *)&client_addr, &addrlen);}while(newfd < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(newfd < 0)ErrExit("accept");/*接收客户端数据*/while(1){do {ret = recv(newfd, buf, BUFSIZ, 0);}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(ret < 0)ErrExit("recv");else if(!ret)break;elseprintf("[%s:%d]buf:%s\n", inet_ntoa(client_addr.sin_addr), //IP地址ntohs(client_addr.sin_port), buf);//端口号,buf}close(newfd);close(fd);return 0;
}

tcp.h

#ifndef _TCP_H_
#define _TCP_H_#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>#define BACKLOG 5  //在未完成连接队列中的允许最大连接数#define ErrExit(msg) do { perror(msg); \exit(EXIT_FAILURE); } while(0)typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;#endif
  1. 编译 gcc -o server server.c -Wall
  2. 运行 ./server 0 8080 ‘0’ 代指本地回环地址,通常为127.0.0.1
  3. nc命令模拟客户端 nc 0 8080
  4. 发送数据,验证程序

在这里插入图片描述

client.c 客户端

#include "tcp.h"int main(int argc, char *argv[])
{int fd;int ret;char buf[BUFSIZ] = {"===test==="};Addr_in addr;/*检查参数*/if(argc < 3){fprintf(stderr, "%s <addr><port>\n", argv[0]);exit(EXIT_FAILURE);}/*创建套接字*/if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)ErrExit("socket");/*设置通信结构体*/bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*发起连接请求*/if( connect(fd, (Addr *)&addr, sizeof(addr) ) )ErrExit("connect");/*发送数据*/while(1){do {ret = send(fd, buf, BUFSIZ, 0);}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(ret < 0)ErrExit("recv");else if(!ret)break;printf("send data:%s", buf);fflush(stdout);getchar();}close(fd);return 0;
}
  1. 编译 gcc -o client client.c
  2. 运行服务端 ./sever 0 8080
  3. 运行客户端./client 0 8080
  4. 开始通信,按一下回车发一次数据

在这里插入图片描述

函数封装

将上面写的代码封装成函数方便后期阅读,一共四个代码文件:tcp.c、tcp.h、server.c、client.c

tcp.c

#include "tcp.h"void Argment(int argc, char *argv[]){if(argc < 3){fprintf(stderr, "%s <addr><port>\n", argv[0]);exit(EXIT_FAILURE);}
}int SocketInit(char *argv[], bool server){int fd;Addr_in addr;func_t func = server?bind:connect;/*创建套接字*/if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)ErrExit("socket");/*设置通信结构体*/bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*地址快速重用*/int b_reuse = 1;setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int) );/*发起连接请求或绑定地址*/if( func(fd, (Addr *)&addr, sizeof(addr) ) )ErrExit("connect or bind");if(server){/*监听模式*/if( listen(fd, BACKLOG) )ErrExit("listen");}return fd;
}

tcp.h

#ifndef _TCP_H_
#define _TCP_H_#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdbool.h>#define BACKLOG 5#define ErrExit(msg) do { perror(msg); \exit(EXIT_FAILURE); } while(0)typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;typedef int (* func_t)(int, const Addr *, socklen_t);void Argment(int argc, char *argv[]);
int SocketInit(char *argv[], bool server);
#endif

server.c

#include "tcp.h"int main(int argc, char *argv[])
{int fd, newfd;int ret;char buf[BUFSIZ];Addr_in client_addr;socklen_t addrlen = sizeof(Addr_in);/*检查参数*/Argment(argc, argv);/*创建服务端套接字*/fd = SocketInit(argv, true);/*接收客户端连接*/do {newfd = accept(fd, (Addr *)&client_addr, &addrlen);}while(newfd < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(newfd < 0)ErrExit("accept");/*接收客户端数据*/while(1){do {ret = recv(newfd, buf, BUFSIZ, 0);}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(ret < 0)ErrExit("recv");else if(!ret)break;elseprintf("[%s:%d]buf:%s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buf);}close(newfd);close(fd);return 0;
}

client.c

#include "tcp.h"int main(int argc, char *argv[])
{int fd;int ret;char buf[BUFSIZ] = {"===test==="};/*检查参数*/Argment(argc, argv);fd = SocketInit(argv, false);/*发送数据*/while(1){do {ret = send(fd, buf, BUFSIZ, 0);}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(ret < 0)ErrExit("recv");else if(!ret)break;printf("send data:%s", buf);fflush(stdout);getchar();}close(fd);return 0;
}

编译运行

  1. 服务端编译:gcc -g -Wall server.c tcp.c -o server
  2. 客户端编译:gcc -g -Wall client.c tcp.c -o client
  3. 运行服务端:./server
  4. 运行客户端:./client

为了方便编译,写一个Makefile文件

Makefile

all:server client
CC=gcc
CFLAGS=-g -Wallserver:tcp.c server.cclient:tcp.c client.cclean:rm server client
  • 这样编译时输入make 命令即可
  • 清理生成的可执行文件输入clean 命令即可
  • 在这里插入图片描述

2.实现文件传输

sever.c

添加了接收文件名、创建文件、接收文件

#include "tcp.h"int main(int argc, char *argv[])
{int fd, newfd, file_fd;int ret;char buf[BUFSIZ] = {};Addr_in client_addr;socklen_t addrlen = sizeof(Addr_in);/*检查参数*/Argment(argc, argv);/*创建服务端套接字*/fd = SocketInit(argv, true);/*接收客户端连接*/do {newfd = accept(fd, (Addr *)&client_addr, &addrlen);}while(newfd < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(newfd < 0)ErrExit("accept");/*接收文件名字*/ret = SocketDataHandle(newfd, buf, BUFSIZ, recv);/*创建文件*/if( (file_fd = open(buf, O_WRONLY|O_CREAT, 0660) ) < 0)ErrExit("file_fd");buf[0] = OK;SocketDataHandle(newfd, buf, 1, (DataHand_t)send);/*接收文件*/while(1){ret = SocketDataHandle(newfd, buf, BUFSIZ, recv);if(!ret)break;write(file_fd, buf, ret);}close(file_fd);close(newfd);close(fd);return 0;
}

client.c

添加了发送文件名、发送文件

#include "tcp.h"
#define FILENAME "picture.jpg"//要发送的文件int main(int argc, char *argv[])
{int fd, file_fd;int ret;char buf[BUFSIZ];/*检查参数*/Argment(argc, argv);fd = SocketInit(argv, false);/*打开文件*/if( (file_fd = open(FILENAME, O_RDONLY) ) < 0)ErrExit("open");/*发送文件名字*/SocketDataHandle(fd, FILENAME, strlen(FILENAME), (DataHand_t)send);SocketDataHandle(fd, buf, 1, recv);/*发送文件*/if(buf[0] == OK){while(1){do {ret = read(file_fd, buf, BUFSIZ);}while(ret < 0 && errno == EINTR);if( ret < 0)ErrExit("read");if(!ret)break;ret = SocketDataHandle(fd, buf, ret, (DataHand_t)send);if(!ret)break;}}close(file_fd);close(fd);return 0;
}

tcp.c

添加了发送接收函数SocketDataHandle()

#include "tcp.h"void Argment(int argc, char *argv[]){if(argc < 3){fprintf(stderr, "%s <addr><port>\n", argv[0]);exit(EXIT_FAILURE);}
}int SocketInit(char *argv[], bool server){int fd;Addr_in addr;func_t func = server?bind:connect;/*创建套接字*/if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)ErrExit("socket");/*设置通信结构体*/bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*发起连接请求或绑定地址*/if( func(fd, (Addr *)&addr, sizeof(addr) ) )ErrExit("connect");if(server){/*地址快速重用*/int b_reuse = 1;setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int) );/*监听模式*/if( listen(fd, BACKLOG) )ErrExit("listen");}return fd;
}int SocketDataHandle(int fd, void *buf, size_t len, DataHand_t datahandle){int ret;char *str = datahandle == recv ? "recv" :"send";do {ret = datahandle(fd, buf, len, 0);} while(ret < 0 && errno == EINTR);if(ret < 0)ErrExit(str);return ret;
}

tcp.h

#ifndef _TCP_H_
#define _TCP_H_#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>#define BACKLOG 5#define ErrExit(msg) do { perror(msg); \exit(EXIT_FAILURE); } while(0)typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;typedef int (* func_t)(int, const Addr *, socklen_t);
typedef ssize_t(* DataHand_t)(int, void *, size_t, int);void Argment(int argc, char *argv[]);
int SocketInit(char *argv[], bool server);
int SocketDataHandle(int fd, void *buf, size_t len, DataHand_t datahandle);#include <sys/stat.h>
#include <fcntl.h>#define OK '1'#endif

Makeifle

添加了mv_client命令,通过终端该文件夹下输入make mv_client ,即可将client文件移动到/home/linux/Study/study8/Project/test/目录下

all:server client
CC=gcc
CFLAGS=-g -Wallserver:tcp.c server.cclient:tcp.c client.cmv_client:mv client /home/linux/Study/study8/Project/test/
clean:rm server client

编译运行

  1. 将文件 picture.jpg 放在客户端目录:/home/linux/Study/study8/Project/test/
  2. 切换到服务端的目录下:cd /home/linux/Study/study8/Project/v3/
  3. 编译:make
  4. 移动客户端可执行文件:make mv_client
  5. 运行服务端:./server 0 8080
  6. 再开一个终端,切换到客户端目录下:cd /home/linux/Study/study8/Project/test/
  7. 运行客户端:./client 0 8080
  8. 查看服务端目录,文件picture.jpg 是否被传输

在这里插入图片描述

3.实现用文件名传输

server.c

#include "tcp.h"int main(int argc, char *argv[])
{int fd, newfd, file_fd;int ret;char buf[BUFSIZ] = {};Addr_in client_addr;socklen_t addrlen = sizeof(Addr_in);/*检查参数*/Argment(argc, argv);/*创建服务端套接字*/fd = SocketInit(argv, true);/*接收客户端连接*/do {newfd = accept(fd, (Addr *)&client_addr, &addrlen);}while(newfd < 0 && errno == EINTR); //如果信号导致的错误,继续执行if(newfd < 0)ErrExit("accept");/*接收文件名字*/ret = SocketDataHandle(newfd, buf, BUFSIZ, recv);/*创建文件*/if( (file_fd = open(buf, O_WRONLY|O_CREAT, 0660) ) < 0)ErrExit("file_fd");buf[0] = OK;SocketDataHandle(newfd, buf, 1, (DataHand_t)send);/*接收文件*/while(1){ret = SocketDataHandle(newfd, buf, BUFSIZ, recv);if(!ret)break;write(file_fd, buf, ret);}close(file_fd);close(newfd);close(fd);return 0;
}

client.c

修改为运行时只读入一个参数‘文件名’

IP地址和端口号改为从.info文件中读取

#include "tcp.h"#define INFOFILE ".info"int main(int argc, char *argv[])
{int fd, file_fd;int ret;FILE *fp;char buf[BUFSIZ];char *filename = argv[1];if(argc < 2){printf("%s <filename>\n", argv[0]);exit(0);}/*通过配置文件获取IP地址和端口号*/if( (fp = fopen(INFOFILE, "r") ) == NULL)ErrExit("fopen");fgets(buf, 20, fp); //读取第一行buf[strlen(buf)-1] = '\0';argv[1] = buf;fgets(&buf[20], 20, fp);//读取第二行buf[strlen(&buf[20])-1+20] = '\0';argv[2] = &buf[20];fd = SocketInit(argv, false);/*打开文件*/if( (file_fd = open(filename, O_RDONLY) ) < 0)ErrExit("open");/*发送文件名字*/SocketDataHandle(fd, filename, strlen(filename), (DataHand_t)send);SocketDataHandle(fd, buf, 1, recv);/*发送文件*/if(buf[0] == OK){while(1){do {ret = read(file_fd, buf, BUFSIZ);}while(ret < 0 && errno == EINTR);if( ret < 0)ErrExit("read");if(!ret)break;ret = SocketDataHandle(fd, buf, ret, (DataHand_t)send);if(!ret)break;printf("ret = %d\n", ret);}}close(file_fd);close(fd);return 0;
}

tcp.c

#include "tcp.h"void Argment(int argc, char *argv[]){if(argc < 3){fprintf(stderr, "%s <addr><port>\n", argv[0]);exit(EXIT_FAILURE);}
}int SocketInit(char *argv[], bool server){int fd;Addr_in addr;func_t func = server?bind:connect;/*创建套接字*/if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)ErrExit("socket");/*设置通信结构体*/bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );if (inet_aton(argv[1], &addr.sin_addr) == 0) {fprintf(stderr, "Invalid address\n");exit(EXIT_FAILURE);}/*发起连接请求或绑定地址*/if( func(fd, (Addr *)&addr, sizeof(addr) ) )ErrExit("connect");if(server){/*地址快速重用*/int b_reuse = 1;setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int) );/*监听模式*/if( listen(fd, BACKLOG) )ErrExit("listen");}return fd;
}int SocketDataHandle(int fd, void *buf, size_t len, DataHand_t datahandle){int ret;char *str = datahandle == recv ? "recv" :"send";do {ret = datahandle(fd, buf, len, 0);} while(ret < 0 && errno == EINTR);if(ret < 0)ErrExit(str);return ret;
}

tcp.h

#ifndef _TCP_H_
#define _TCP_H_#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>#define BACKLOG 5#define ErrExit(msg) do { perror(msg); \exit(EXIT_FAILURE); } while(0)typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;typedef int (* func_t)(int, const Addr *, socklen_t);
typedef ssize_t(* DataHand_t)(int, void *, size_t, int);void Argment(int argc, char *argv[]);
int SocketInit(char *argv[], bool server);
int SocketDataHandle(int fd, void *buf, size_t len, DataHand_t datahandle);#include <sys/stat.h>
#include <fcntl.h>#define OK '1'#endif

.info

用来储存IP地址和端口号

ls命令查看它时,加-a选项

127.0.0.1
8080

文件位置

server.c,client.c,tcp.c,tcp.h,在服务端文件夹

.info,爱的箴言-郑钧.mp3,在客户端文件夹

编译运行

  1. 切换到服务端的目录下:cd /home/linux/Study/study8/Project/v4/
  2. 编译:make
  3. 移动客户端可执行文件的客户端目录下:make mv_client
  4. 运行服务端:./server 0 8080
  5. 再开一个终端,切换到客户端目录下:cd /home/linux/Study/study8/Project/test/
  6. 运行客户端:./client 爱的箴言-郑钧.mp3
  7. 查看服务端目录,文件爱的箴言-郑钧.mp3 是否被传输,试听一下

在这里插入图片描述

项目基本的功能已经实现,请自己尝试完成项目,完整项目代码看下一章

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

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

相关文章

MES管理系统中的质量管理活动是什么

在制造业的广阔天地中&#xff0c;质量管理如同航船的指南针&#xff0c;指引着产品品质的航行方向。而随着科技的日新月异&#xff0c;MES管理系统在质量管理领域扮演着越来越重要的角色。MES管理系统不仅连接了企业的管理层与车间生产现场&#xff0c;更在质量管理的各个环节…

RS485常见问题及解决方法

RS485常见问题及解决方法 RS485总线是工业上最常用的通信方式之一&#xff0c;在实际布线或使用过程中通常会出现一系列问题&#xff0c;今天总结一些平时RS485通讯可能会出现的通讯问题及其解决方法以供大家参考。 一、什么是RS485&#xff1f; RS485&#xff0c;全称为TIA…

QT(超详细从0开始)

目录 1.2 Qt的优点 2.安装Qt 3.创建项目 4.解读Qt自动生成的代码 ​编辑 5.Qt Designer 6.Qt对象数 7.Qt乱码问题 8.Qt坐标系的认识 9.信号和槽 9.1 connect 9.2 自定义槽函数 9.3 自定义信号 9.4 断开信号链接&#xff08;disconnect&#xff09; 9.5.lambda表…

家庭智能助手:Kompas AI引领家居智能化新纪元

一、引言 在数字化浪潮的推动下&#xff0c;现代家庭生活正迅速向智能化转型。从简单的自动化设备到复杂的智能家居系统&#xff0c;智能技术正悄无声息地改变我们的日常生活。Kompas AI作为一款前沿的家庭智能助手&#xff0c;不仅预示着家庭生活的未来趋势&#xff0c;更以其…

帕金森运动小贴士,壁纸里的健康密码

&#x1f31f; 在这个快节奏的时代&#xff0c;我们越来越关注身体的健康。今天&#xff0c;我想和大家分享一份特别的小贴士&#xff0c;它藏在一张精致的小红书壁纸里&#xff0c;是关于帕金森病的运动建议。帕金森病是一种常见的神经系统疾病&#xff0c;适当的运动对于缓解…

小米充电宝怎么样?西圣、小米、罗马仕充电宝测评谁是卷王!

充电宝说实话在我们日常生活中还是非常常见的一个出门必备的充电设备&#xff0c;除了出门必须带数据线之外&#xff0c;充电宝也是不例外的&#xff0c;对于手机不耐电的朋友来说在外面有一个充电宝简直就是蓄电“救星”&#xff0c;什么都可以不带但是充电宝是必带的一款装备…

Ubuntu 在线或离线安装docker

查看自己的ubuntu版本 在终端中执行以下命令&#xff1a; lsb_release -a 终端中的复制粘贴&#xff1a; ctrl shift c ctrl shifr v 在线安装docker&#xff08;不需要外网&#xff09;: 命令行安装&#xff1a;Ubuntu Docker -- 从入门到实践 看完…

6月17日(周一),AH 股行情总结

AI手机及苹果概念股全日走强&#xff0c;领益智造、山东精密等多股涨停&#xff0c;立讯精、歌尔股份涨逾6% 。新车型秦L销售预期提振股价&#xff0c;比亚迪涨超1% &#xff1b;航运、煤炭、地产板块下跌。 文章正文 周一&#xff0c;A股低开高走&#xff0c;上证指数收跌0.…

2024年了! 为什么还在用串口服务器?

在数字化飞速发展的2024年&#xff0c;串口服务器这一看似古老的技术仍然在工业自动化、远程监控和数据通信等领域发挥着重要作用。本文将从串口服务器的定义、功能、优势和使用场景四个方面来探讨&#xff0c;为什么串口服务器在今天仍然被广泛使用。 1. 什么是串口服务器 串口…

拉依达的嵌入式学习和秋招经验

拉依达的嵌入式学习和秋招经验 你好&#xff0c;我是拉依达。目前我已经结束了自己的学生生涯&#xff0c;开启了人生的下一个阶段。 从研二准备秋招开始&#xff0c;我就逐渐将自己的学习笔记陆续整理并到CSDN上发布。起初只是作为自己学习的备份记录&#xff0c;后续得到了越…

gpustat

使用gpustat命令查看GPU的资源使用情况&#xff0c;例如&#xff1a; 但是需要先安装&#xff1a; pip install gpustat

ubuntu安装idea

下载这个文件解压&#xff0c;我的解压在了用户目录下的X86下&#xff0c;接下来直接运行bin下的sh就能启动&#xff0c;想要在固定栏用以下步骤 创建桌面条目文件&#xff1a; 在 ~/.local/share/applications 目录中创建一个新的 .desktop 文件。例如&#xff0c;可以命名…

ubuntu16.04升级cmake版本至3.21.0

ubuntu16.04升级cmake版本至3.21.1 前言&#xff1a;建议先看完文章&#xff0c;再逐步跟做。 相对来说。ubuntu16.04是比较稳定一版&#xff0c;但其默认安装的cmake版本是3.5.1&#xff0c;假如我们需要用到更高的cmake版本&#xff0c;则需要手动升级cmake版本号。以cmake3.…

React-配置json-server

安装json-server&#xff1a;json-server工具准备后端接口服务环境_jsonserver临时后端-CSDN博客 在package.json文件中的scripts添加&#xff1a; "serve":"json-server json文件路径 --port 端口号" 在终端输入命令npm run serve&#xff0c;就可以启动…

FPGA学习最好的2个网站?

自学FPGA最好的两个网站: Xilinx官方网站: ​网址链接&#xff1a; https://www.amd.com/zh-cn.html Xilinx Wiki - Confluence (http://atlassian.net) Xilinx GitHub&#xff08;https://github.com/Xilinx&#xff09; 电子创新网赛灵思社区 | 电子创新网 (http://eet…

期货到底难在哪里?

第一难&#xff1a;使用杠杠&#xff0c;杠杠放大的其实是你性格、天赋和技能上的弱点&#xff0c;同时相应缩小你这三个方面的优点&#xff1b;第二难&#xff1a;双向交易。如果只能做多&#xff0c;理论上你每次交易将有50%的概率盈利。现在既能做多又能做空&#xff0c;只剩…

RocketMQ:揭秘电商巨头背后的消息队列秘密

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!​​​​​​​ 大家好,我是小米,一个技术爱好者,今天想和大家分享一下我最近深入研究的一个消息队列系统——RocketMQ。这款消息队列系统借鉴了Kafk…

如何挑到高质量的静态IP代理?

在数字化时代&#xff0c;静态住宅IP代理已成为网络活动中不可或缺的一部分。无论是数据采集、网站访问&#xff0c;还是其他需要隐藏真实IP地址的在线活动&#xff0c;高质量的静态住宅IP代理都发挥着至关重要的作用。今天IPIDEA代理IP将详细介绍如何获取高质量的静态住宅IP代…

如何学习VBA_3.3.3:VBA对于工作簿、工作表的一般操作

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的劳动效率&#xff0c;而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册&#xff0c;现在已经全部完成&#xff0c;希望大家利用、学习。 如果…

软件安全测评有哪些测试流程?第三方检测机构进行安全测评的好处

在今天的高科技时代&#xff0c;软件产品已经成为人们生活和工作的重要组成部分。然而&#xff0c;与其普及和深入应用的&#xff0c;软件安全问题也日益凸显。 为了保障软件产品在使用过程中的安全性&#xff0c;进行安全测评是必不可少的。安全测评可以全面评估软件系统的安…