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

news2024/12/29 10:37:37

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;
		else
			printf("[%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;
		else
			printf("[%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 -Wall

server:tcp.c server.c

client:tcp.c client.c

clean:
	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 -Wall

server:tcp.c server.c

client:tcp.c client.c

mv_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.coloradmin.cn/o/1831404.html

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

相关文章

死锁预防之银行家算法

死锁预防之银行家算法 第一章 概述 Dijkstra提出了一种能够避免死锁的调度算法,称为银行家算法。 它的模型基于一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,每个客户都有一个贷款额度,银行家知道不可能所有客户同时都需要最大贷款额,所以他只保留一定单位…

wps 二维数据转转一维度数据

HSTACK(TOCOL(C2:H2&A3:A8),TOCOL(B3:B8&C1:H1),TOCOL(C3:H8))

------构造类型数据—结构体---- + ----函数-----

构造类型数据——结构体 1&#xff09;结构体的基本概念 结构体&#xff08;struct&#xff09;是C语言&#xff08;以及其他一些编程语言&#xff09;中用于将不同类型的数据组合成一个单一类型的方式。这种数据类型允许你将多个变量&#xff08;可能是不同类型&#xff09;…

iconfont的使用(超简单)

iconfont的使用&#xff08;超简单&#xff09; 1、iconfont 是什么&#xff1f;2、使用2.1、新建项目2.2、搜图标 添加 至项目中2.3、下载iconfont的包文件![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/91a0a07cd4b74798b7fb333dddca7724.png)2.4、画一个文件夹…

基于Python的花卉识别分类系统【W9】

简介&#xff1a; 基于Python的花卉识别分类系统利用深度学习和计算机视觉技术&#xff0c;能够准确识别和分类各种花卉&#xff0c;如玫瑰、郁金香和向日葵等。这种系统不仅有助于植物学研究和园艺管理&#xff0c;还在生态保护、智能农业和市场销售等领域展现广泛应用前景。随…

springboot原理篇-bean管理

springboot原理篇-bean管理&#xff08;二&#xff09; 我们今天主要学习IOC容器中Bean的其他使用细节&#xff0c;主要学习以下三方面&#xff1a; 如何从IOC容器中手动的获取到bean对象bean的作用域配置管理第三方的bean对象 一、获取Bean 了解即可&#xff0c;默认情况下…

将Vite添加到您现有的Web应用程序

Vite&#xff08;发音为“veet”&#xff09;是一个新的JavaScript绑定器。它包括电池&#xff0c;几乎不需要任何配置即可使用&#xff0c;并包括大量配置选项。哦——而且速度很快。速度快得令人难以置信。 本文将介绍将现有项目转换为Vite的过程。我们将介绍别名、填充webp…

Springboot整合阿里云ONS RocketMq(4.0 http)

1. 引入依赖 <!--阿里云ons&#xff0c;方便的接入到云服务--> <dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</artifactId><version>1.8.4.Final</version> </dependency>2. 配置 配…

牛客周赛 46 F 祥子拆团

原题链接&#xff1a;F-祥子拆团 题目大意&#xff1a;多测&#xff0c;每次给a,b&#xff0c;要将a分解成b个数相乘&#xff0c;问有多少种分的方法。 思路&#xff1a;对a进行质因数分解&#xff0c;对每一个质数计数&#xff0c;然后分到b个篮子里面&#xff0c;允许篮子里…

SFNC —— 图像格式控制(三)

系列文章目录 SFNC —— 标准特征命名约定&#xff08;一&#xff09; SFNC —— 设备控制&#xff08;二&#xff09; SFNC —— 图像格式控制&#xff08;三&#xff09; 文章目录 系列文章目录4、图像格式控制&#xff08;Image Format Control&#xff09;1. 图像格式控制&…

Flink系列之:Generating Watermarks生成水印

Flink系列之&#xff1a;Generating Watermarks生成水印 一、水印策略简介二、使用水印策略三、处理闲置资源四、水印对齐五、编写水印生成器六、编写周期性水印生成器七、编写标点水印生成器八、水印策略和 Kafka 连接器九、Operators如何处理水印十、已弃用的AssignerWithPer…

电信网关配置管理系统 del_file.php 前台RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

护眼台灯哪个牌子最好?学生台灯护眼好还是防近视好

当前&#xff0c;我国正面临日益严峻的青少年近视挑战。从小学到大学&#xff0c;学生的近视率居高不下&#xff0c;其中高度近视的比例更是令人担忧。这不仅直接威胁到孩子们的身体健康和视力发育&#xff0c;从长远来看&#xff0c;还可能对国家的未来发展和国家安全产生不利…

RTSP/Onvif安防监控平台EasyNVR抓包命令tcpdump使用不了,该如何解决?

安防视频监控汇聚EasyNVR智能安防视频监控平台&#xff0c;是基于RTSP/Onvif协议的安防视频平台&#xff0c;可支持将接入的视频流进行全平台、全终端分发&#xff0c;分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。平台可提供的视频能力包括&#xff1a;…

gitlab仓库中用git bash生成不是默认路径的ssh秘钥

使用命令 ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 会在默认路径生成秘钥&#xff0c;&#xff08;C:\Users\用户\.ssh\&#xff09; 想要修改默认路径使用如下命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"…

软链接和硬链接的详解 (Linux系统下)

文章目录 硬链接的引入软链接和硬链接的形成软链接硬链接 软硬链接区别的探究硬链接数结语 硬链接的引入 当我们在命令行中输入ll时会出现很多行信息&#xff0c;详情请看下面的图 ~~~~εεε(&#xffe3;▽&#xffe3;) 我在之前的几篇Linux的文章也讲过哦 (o&#xff9f;v…

2024最新版Node.js下载安装及环境配置教程(非常详细)

一、进入官网地址下载安装包 官网&#xff1a;Node.js — Run JavaScript Everywhere 其他版本下载&#xff1a;Node.js — Download Node.js (nodejs.org) 选择对应你系统的Node.js版本 二、安装程序 &#xff08;1&#xff09;下载完成后&#xff0c;双击安装包&#xf…

小白Linux提权

1.脏牛提权 原因&#xff1a; 内存子系统处理写入复制时&#xff0c;发生内存条件竞争&#xff0c;任务执行顺序异常&#xff0c;可导致应用崩溃&#xff0c;进一步执行其他代码。get_user_page内核函数在处理Copy-on-Write(以下使用COW表示)的过程中&#xff0c;可能产出竞态…

项目方案:社会视频资源整合接入汇聚系统解决方案(六)

目录 一、概述 1.1 应用背景 1.2 总体目标 1.3 设计原则 1.4 设计依据 1.5 术语解释 二、需求分析 2.1 政策分析 2.2 业务分析 2.3 系统需求 三、系统总体设计 3.1设计思路 3.2总体架构 3.3联网技术要求 四、视频整合及汇聚接入 4.1设计概述 4.2社会视频资源分类…