基于TCP协议的简易FTP云盘

基于TCP协议的简易FTP云盘

创建基于TCP协议的简易FTP云盘涉及多个方面的知识,包括网络编程、文件传输、用户认证等。以下是一种简单的实现思路,你可以根据需要进行调整和扩展:

  1. 选择编程语言: 选择你熟悉的编程语言,例如Python、Java等。

  2. 网络编程: 使用套接字(Socket)进行网络通信。服务端和客户端之间通过TCP协议建立连接,服务端监听特定端口,等待客户端连接。

  3. 用户认证: 在客户端连接到服务器后,需要进行用户认证。可以实现简单的用户名和密码认证,或者使用其他认证方式,如密钥认证。

  4. 命令交互: 定义FTP命令,例如上传文件、下载文件、列出文件列表等。客户端通过发送这些命令到服务器,服务器执行相应的操作。

  5. 文件传输: 实现文件的上传和下载功能。可以使用FTP的二进制传输模式,按块传输文件。

  6. 目录管理: 允许用户创建、删除、列出目录。服务器需要维护用户的文件和目录结构。

  7. 错误处理: 实现错误处理机制,对于不合法的命令或操作进行适当的处理,并向客户端发送错误信息。

  8. 安全性考虑: 考虑安全性问题,包括数据加密、用户权限管理等。

以下是一个简单的Python示例,演示了一个基于TCP协议的简易FTP云盘的服务端和客户端的通信:

# 服务端代码
import socketserver_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 12345))
server_socket.listen(5)print("Server listening on port 12345")while True:client_socket, addr = server_socket.accept()print("Connection from", addr)data = client_socket.recv(1024).decode()print("Received:", data)response = "Hello from server"client_socket.send(response.encode())client_socket.close()# 客户端代码
import socketclient_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 12345))message = "Hello from client"
client_socket.send(message.encode())data = client_socket.recv(1024).decode()
print("Received from server:", data)client_socket.close()

这只是一个简单的例子,实际的FTP云盘需要更多的功能和安全性考虑。你可以在此基础上逐步扩展和完善。

使用套接字(Socket)库来进行网络编程

在C语言中,你同样可以使用套接字(Socket)库来进行网络编程。下面是一个简单的基于C语言的TCP服务器和客户端示例,用于建立简易FTP云盘通信:

服务器端 (ftp_server.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345
#define BUFFER_SIZE 1024void handle_client(int client_socket) {char buffer[BUFFER_SIZE];ssize_t bytes_received;// Receive data from the clientbytes_received = recv(client_socket, buffer, sizeof(buffer), 0);if (bytes_received < 0) {perror("Error receiving data");close(client_socket);exit(EXIT_FAILURE);}// Process the received data (you can implement FTP commands here)// Send a response back to the clientconst char *response = "Hello from server";send(client_socket, response, strlen(response), 0);// Close the client socketclose(client_socket);
}int main() {int server_socket, client_socket;struct sockaddr_in server_addr, client_addr;socklen_t client_len = sizeof(client_addr);// Create socketserver_socket = socket(AF_INET, SOCK_STREAM, 0);if (server_socket < 0) {perror("Error creating socket");exit(EXIT_FAILURE);}// Bind socket to portmemset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("Error binding socket");close(server_socket);exit(EXIT_FAILURE);}// Listen for incoming connectionsif (listen(server_socket, 5) < 0) {perror("Error listening for connections");close(server_socket);exit(EXIT_FAILURE);}printf("Server listening on port %d\n", PORT);while (1) {// Accept connection from clientclient_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);if (client_socket < 0) {perror("Error accepting connection");close(server_socket);exit(EXIT_FAILURE);}// Handle the client in a separate functionhandle_client(client_socket);}// Close the server socketclose(server_socket);return 0;
}

客户端 (ftp_client.c)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 12345
#define BUFFER_SIZE 1024int main() {int client_socket;struct sockaddr_in server_addr;char buffer[BUFFER_SIZE];// Create socketclient_socket = socket(AF_INET, SOCK_STREAM, 0);if (client_socket < 0) {perror("Error creating socket");exit(EXIT_FAILURE);}// Connect to servermemset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(PORT);if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("Error connecting to server");close(client_socket);exit(EXIT_FAILURE);}// Send data to the serverconst char *message = "Hello from client";send(client_socket, message, strlen(message), 0);// Receive response from the serverssize_t bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);if (bytes_received < 0) {perror("Error receiving data");close(client_socket);exit(EXIT_FAILURE);}// Process the received data (you can print or use as needed)printf("Received from server: %.*s\n", (int)bytes_received, buffer);// Close the client socketclose(client_socket);return 0;
}

请注意,这只是一个基础的示例,你可能需要根据具体需求实现更多的FTP功能和安全性考虑。

项目实现

  这个项目分成ftp客户端及服务端,实现的功能和Linux开源的ftp服务器类似,客戶端通过网络,远程获取服务端磁盘上的文件夹内容,下载文件,上传文件等功能。(基本功能描述)

  ftp服务器用到的是Socket通信,当收到客户端接入的时候,创建子进程对接连接,子进程启动后分析来自客户端的指令。比如收到get file1的指令,是客户端想要获取file1文件的,先用strstr函数进行字符串分割,获取到文件名,在判断文件是否存在,如果文件存在,就读取文件內容,再将內容通过套接字发给客户端,客户端收到数据后,创建文件,并将收到的数据写入文件,完成文件的远程下载。

  上传文件和下载文件类似,主要还是涉及文件的操作,字符串的操作,以及网络编程。

  还支持了Is、pwd、cd等Linux系统常用的指令。普通指令的实现用popen来调用系统质量,并读取执行的结构。如果不需要获取执行结果,用system函数调用就可以了。

实现功能点

利用socket,建立起服务端与客户端的对接;(服务端能支持多台客户端的同时连接)

客户端

ls:查看服务端当前路径下的所有文件;
lls:查看客户端当前路径下的所有文件;
cd xx:服务端进入xx路径;
lcd xx:客户端进入xx路径;
pwd:查看服务端当前路径;
lpwd:查看客户端当前路径;
get xx:从服务端当前路径获取xx文件到客户端当前路径上;
put xx:将客户端当前路径xx文件发送到服务端当前路径;
quit:断开客户端连接;

服务端

1、不断监听客户端的指令(等待指令)。
2、在接收上面客户端的指令后,去执行指令。

代码实现

服务端

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include "msg.h"int get_cmd_type(char *cmd)    // 将从客户端发送过来的指令转换成整数返回
{if (!strcmp("ls", cmd))			return LS;if (!strcmp("quit", cmd))		return QUIT;if (!strcmp("pwd", cmd))		return PWD;if (strstr(cmd, "cd") != NULL)	return CD;if (strstr(cmd, "get") != NULL)	return GET;if (strstr(cmd, "put") != NULL)	return PUT;return 11;
}char *getdir(char *cmsg)      // 将需要带参数的指令进行指令参数分离,返回分离出的参数
{char *p;p = strtok(cmsg, " ");   // 以空格分离p = strtok(NULL, " ");return p;
}void msg_handle(struct Msg msg, int fd)  // 对客户端发送的消息进行相对应处理
{char dataBuf[1024] = {0};     	// 用来存放GET的文件数据char *file = NULL;       		// 用来放GET的文件名int fdfile;         			// GET时open的fdchar *dir;    					// 存放cd函数进入地址,即文件夹名字printf("cmd:%s\n", msg.cmd);     	// 打印客户端发来消息里的指令名int ret = get_cmd_type(msg.cmd);	// 获取指令所对应的整数switch (ret){case LS:case PWD:FILE *r = popen(msg.cmd, "r");			// 使用popen调用msg.cmd里的ls或pwd指令,并将运行结果读入到文件流rfread(msg.cmd, sizeof(msg.cmd), 1, r);	// 将文件流r里的数据读入到msg.cmdwrite(fd, &msg, sizeof(msg));			// 将msg里的数据通过fd发送给客户端break;case CD:dir = getdir(msg.cmd);		// 将提取cd后面的参数,即文件夹名字,赋给dirprintf("dir:%s\n", dir);	// 服务端打印要进入的文件夹名字chdir(dir);					// 使用chdir改变服务器当前路径,进入到dir文件夹,不使用systembreak;case GET:	// 从服务端获取文件file = getdir(msg.cmd);					// 分离get后面的参数,即文件名,赋给fileif (access(file, F_OK) == -1) {			// 使用access函数判断该文件是否存在,不存在返回值为-1strcpy(msg.cmd, "no the file!");	// 复制该字符串到msg.cmdwrite(fd, &msg, sizeof(msg));		// 将该字符串发送给客户端}else {fdfile = open(file, O_RDWR);			// 将file文件以可读可写方式打开read(fdfile, dataBuf, sizeof(dataBuf));	// 将fdfile中的数据读入到dataBuf中close(fdfile);							// 关闭文件strcpy(msg.cmd, dataBuf);				// 将dataBuf中的数据复制到msg.cmd中write(fd, &msg, sizeof(msg));			// 将msg里的数据通过fd发送给客户端}break;case PUT:	// 将服务端文件发送给客户端fdfile = open(getdir(msg.cmd), O_RDWR|O_CREAT, 0666);	// 将客户端发送的文件在服务端打开,如果没有就创建该文件write(fdfile, msg.buf, strlen(msg.buf));				// 将msg.buf里的数据写入到fdfile所指的文件里close(fdfile);											// 关闭文件break;case QUIT:printf("client quit!\n");exit(-1);}
}int main(int argc, char **argv)
{		int c_fd;  int s_fd;  char readBuf[128];int n_read;struct sockaddr_in s_addr;		// 该结构体用来处理网络通信的地址族、端口号、IP地址等。s_addr服务端struct sockaddr_in c_addr;		// 客户端struct Msg msg;					// 一个包含种类type,指令cmd,缓冲secondBuf的结构体memset(&s_addr, 0, sizeof(struct sockaddr_in));	// 初始化s_addrmemset(&c_addr, 0, sizeof(struct sockaddr_in));if (argc != 3)    // 判断参数个数是否正确,不正确则退出程序{printf("Parameter error: ip prot \n");exit(-1);}// 1.sockets_fd = socket(AF_INET, SOCK_STREAM, 0);   // 创建socket,设置TCP协议if (s_fd == -1) {perror("socket:");exit(-1);}// 2.binds_addr.sin_family = AF_INET;     s_addr.sin_port = htons(atoi(argv[2]));			// argv[2]为端口号,需要通过htons函数将主机字节序转网络字节序inet_aton(argv[1], &s_addr.sin_addr);			// argv[1]为IP地址,需要通过inet_aton将argv[1]字符串转网络字节序bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));	// 绑定设置数据// 3.listenlisten(s_fd,10);	//监听,最多10个// 4.acceptint len = sizeof(struct sockaddr_in);while (1) {c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &len);   // 接受客户端连接if (c_fd == -1) {  // 判断是否连接失败,方便查错perror("accept:");}printf("get connect: %s\n", inet_ntoa(c_addr.sin_addr));   // 连接成功后服务端打印接入的客户端IP地址if (fork() == 0) {	//创建子进程执行客户端所发信息,父进程继续监听,每有一个客户端接入,则创建一个子进程为其服务// 5.readwhile (1) {memset(msg.cmd, 0, sizeof(msg.cmd));	// 初始化msg.cmdn_read = read(c_fd, &msg, sizeof(msg));	// 读取客户端通过c_fd发送过来的消息,没有就阻塞在这,知道消息发送过来if (n_read == -1) {						// 如果n_read==-1,则read失败,方便排错perror("read:");}else if (n_read == 0) {           printf("client out\n");break;}else {msg_handle(msg, c_fd);				// 对客户端发送的消息进行处理}}	}}close(c_fd);close(s_fd);return 0;
}

客户端

#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "msg.h"int get_cmd_type(char *cmd)	// 将命令字符串转换成整数
{if (!strcmp("ls", cmd))	 	return LS;if (!strcmp("quit", cmd)) 	return QUIT;if (!strcmp("lpwd", cmd))	return LPWD;if (!strcmp("pwd", cmd))	return PWD;if (!strcmp("lls", cmd))	return LLS;if (strstr(cmd, "lcd"))		return LCD;     // LCD必须写在CD前,否则当输入lcd时将会返回CDif (strstr(cmd, "cd"))		return CD;if (strstr(cmd, "get"))		return GET;if (strstr(cmd, "put"))		return PUT;return -1;
}char *getdir(char *cmd)      // 分离参数
{char *p;p = strtok(cmd, " ");      // strtok函数会破坏被分解字符串的完整,调用前和调用后的cmd已经不一样了。p = strtok(NULL, " ");return p;
}int cmd_handle(struct Msg msg, int fd)    // 命令处理
{char buf[32];   // put时用来存放msg.cmdint ret;int filefd;char *dir = NULL;ret = get_cmd_type(msg.cmd);      // 判断输入的是哪个命令switch (ret){case LS:case CD:case PWD:                    // 当输入命令是ls、cd、pwd等只对服务器操作的指令时,将msg里的所有数据发送给服务器write(fd, &msg, sizeof(msg));break;case GET:                  // 当为get时,将msg里数据发给服务器write(fd, &msg, sizeof(msg));break;case PUT:strcpy(buf, msg.cmd);     // 当为put时,将msg.cmd复制给bufdir = getdir(buf);         // 分离参数,即所需发送的文件名,buf破坏if (access(dir, F_OK) == -1) {     // 判断客户端是否存在该文件printf("%s not exsit\n", dir);}else {filefd = open(dir, O_RDWR);     // 如果有就打开该文件read(filefd, msg.buf, sizeof(msg.buf));    // 将文件里的数据读入到msg.bufclose(filefd);                 // 关闭文件write(fd, &msg, sizeof(msg));      // 将msg里的数据发送给服务器}break;case LLS:	// 当为lls指令时,在客户端调用ls即可system("ls");    	// system函数调用完ls后,将自动打印输出结果break;case LPWD:	// 当为lpwd指令时,在客户端调用pwd即可system("pwd");    	// system函数调用完pwd后,将自动打印输出结果break;case LCD:	// 当为lcd指令时,分离得出路径名,调用chdir函数改变客户端当前路径dir = getdir(msg.cmd);chdir(dir);break;case QUIT:	// 当为quit指令时,将消息发送给服务器,然后关闭fd,结束客户端strcpy(msg.cmd, "quit");write(fd, &msg, sizeof(msg));close(fd);exit(-1);}return ret;
}void handle_server_msg(int c_fd, struct Msg msg)   // 当接受到ls,get、pwd等指令时,客户端处理服务器发送来的消息
{int n_read;struct Msg msgget;int newfilefd;n_read = read(c_fd, &msgget, sizeof(msgget));   // 将服务器发送来的信息读入msggetif (n_read == 0) {printf("server is out,quit\n");exit(-1);}else if (strstr(msg.cmd, "get")) {         	// 当指令为get时执行char *p = getdir(msg.cmd);            	// 提取想要从服务器端获取的文件名newfilefd = open(p, O_RDWR|O_CREAT, 0600);  // 在客户端打开该文件,没有就创建write(newfilefd, msgget.cmd, strlen(msgget.cmd));   // 将msgget里的数据写入该文件close(newfilefd);putchar('>');fflush(stdout);}else {printf("-------------------------------\n");      // 当指令为ls或pwd时,打印msgget.cmd里的数据printf("\n%s\n", msgget.cmd);printf("-------------------------------\n");putchar('>');fflush(stdout);}
}int main(int argc, char **argv)
{		int c_fd;struct sockaddr_in c_addr;     struct Msg msg;memset(&c_addr, 0, sizeof(struct sockaddr_in));if (argc!=3) {printf("Parameter error: ip prot\n");exit(-1);}//1.socketc_fd = socket(AF_INET, SOCK_STREAM, 0);if (c_fd == -1) {perror("socket:");exit(-1);}c_addr.sin_family = AF_INET;c_addr.sin_port = htons(atoi(argv[2]));inet_aton(argv[1], &c_addr.sin_addr);//2.connectif (connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr)) == -1) {	// connect函数连接服务器,连接失败则返回-1perror("connect:");exit(-1);}printf("connect...\n");                 // 连接成功打印connect...int mark = 0;while (1) {memset(msg.cmd, 0, sizeof(msg.cmd));   // 初始化msg.cmdif (mark == 0) {printf(">");                      // 使界面好看gets(msg.cmd);                   // 从按键获取msg.cmd,即输入指令}if (strlen(msg.cmd) == 0) {           // 如果输入的指令长为0,判断是否打印>,continue后下面语句不执行,从while循环第一句重新开始if (mark == 1) {printf(">");continue;}}mark = 1;int ret = cmd_handle(msg, c_fd);   // 命令处理函数if (ret > IFGO) {       // IFGO的值为3,即指令为lcd、lls、cd、put、quit、lpwd时,打印>,然后重新循环,下面语句不执行putchar('>');fflush(stdout);continue;}if (ret == -1) {              // 如果命令处理函数返回的值为-1,则说明该命令不存在printf("cmd no have!\n");printf(">");fflush(stdout);continue;}handle_server_msg(c_fd, msg);    // 当接受到ls,get、pwd等指令时,客户端处理服务器发送来的消息}return 0;
}

msg.h

#define LS 0
#define GET 1
#define PWD 2#define IFGO 3#define LCD 4
#define LLS 5
#define CD 6
#define PUT 7#define QUIT 8
#define LPWD 9struct Msg
{int type;char cmd[1024];char buf[128];
}; 

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

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

相关文章

看到CSDN的文章上的url后面加了spm呢吗?干嘛用的

https://csdnnews.blog.csdn.net/article/details/135027851?spm1000.2115.3001.5927 像这样的spm有什么作用呢&#xff1f;看到了就想分析下&#xff1a; 在给定的链接中&#xff0c;spm&#xff08;Site Promotion Method&#xff09;是CSDN博客中的一个参数&#xff0c;主…

『 Linux 』重新理解挂起状态

文章目录 &#x1f984; 前言新建状态 &#x1f40b;挂起状态 &#x1f40b;唤入唤出 &#x1f40b;进程与操作系统间的联系 &#x1f40b; &#x1f984; 前言 『 Linux 』使用fork函数创建进程与进程状态的查看中提到了对挂起状态的一个理解&#xff1b; ​ 挂起状态相比于其…

LearnDash LMS ProPanel在线学习系统课程创作者的分析工具

点击阅读LearnDash LMS ProPanel在线学习系统课程创作者的分析工具原文 LearnDash LMS ProPanel在线学习系统课程创作者的分析工具通过整合报告和作业管理来增强您的 LearnDash 管理体验&#xff0c;使您能够发送特定于课程的通信&#xff0c;并显示课程的实时活动&#xff01…

Postgresql在Windows中使用pg_dump实现数据库(指定表)的导出与导入

场景 Windows中通过bat定时执行命令和mysqldump实现数据库备份&#xff1a; Windows中通过bat定时执行命令和mysqldump实现数据库备份_mysqldump bat-CSDN博客 Windows上通过bat实现不同数据库之间同步部分表的部分字段数据&#xff1a; Windows上通过bat实现不同数据库之间…

YOLOv5改进 | SPPF | 将RT-DETR模型AIFI模块和Conv模块结合替换SPPF(全网独家改进)

一、本文介绍 本文给大家带来是用最新的RT-DETR模型中的AIFI模块来替换YOLOv5中的SPPF。RT-DETR号称是打败YOLO的检测模型&#xff0c;其作为一种基于Transformer的检测方法&#xff0c;相较于传统的基于卷积的检测方法&#xff0c;提供了更为全面和深入的特征理解&#xff0c…

Termux搭建nodejs环境

安装nodejs ~ $ pkg install nodejs使用http-server搭建文件下载服务 先安 http-server 并启动 # 安装 http-server 包 ~ $ npm install -g http-server# 启动 http-server 服务 ~ $ http-server Starting up http-server, serving ./http-server version: 14.1.1http-serve…

高可用初探

高可用的本质是主备切换&#xff0c;主备切换对使用者是透明的。 一、路由器高可用 虚拟路由协议VRRP VRRP是一种选择协议&#xff0c;它可以把一个虚拟路由器的责任动态分配到局域网上的 VRRP 路由器中的一台。控制虚拟路由器 IP 地址的 VRRP 路由器称为主路由器&#xff0c;…

【Hadoop面试】HDFS读写流程

HDFS&#xff08;Hadoop Distributed File System&#xff09;是GFS的开源实现。 HDFS架构 HDFS是一个典型的主/备&#xff08;Master/Slave&#xff09;架构的分布式系统&#xff0c;由一个名字节点Namenode(Master) 多个数据节点Datanode(Slave)组成。其中Namenode提供元数…

RISC-V 基础知识汇总

1、指令集 基本指令集 指令集名称描述版本状态RV32I基本整数指令集, 32位元2.1已批准RV32E基本整数指令集(嵌入式系统), 32位元, 16 个暂存器2.0已批准RV64I基本整数指令集, 64位元2.1已批准RV64E基本整数指令集(嵌入式系统), 64位元, 16 个暂存器2.0已批准RV128I基本整数指令…

neuq-acm预备队训练week 10 P1525 [NOIP2010 提高组] 关押罪犯

解题思路 本题用并查集的方法 AC代码 #include <bits/stdc.h> using namespace std; int f[55555]; struct S {int a,b,c;friend inline bool operator<(S a, S b){return a.c>b.c;} } d[100000];int find(int x) {return f[x]x? x:(f[x]find(f[x])); }int mai…

易点易动固定资产管理系统——提升固定资产管理透明度和可靠性

通过全面的资产跟踪、准确的数据记录和实时的报告分析&#xff0c;易点易动系统为企业提供了全新的固定资产管理解决方案&#xff0c;帮助企业实现高效、精确的资产管理&#xff0c;提高运营效率&#xff0c;降低风险&#xff0c;实现可持续发展。 固定资产是企业重要的资源和投…

windows系统通过docker安装redis

文章目录 首先本地要安装了docker,且对docker有一定的了解,不了解可以看我博客哈以前写过安装redis,走的国内镜像.后面有了梯子就不用搞那么麻烦了配置文件映射 注意,指定本地文件需要/开头没有冒号举个栗子/D/server/redis/64bit/docker7_2_0redis.conf命令 首先本地要安装了d…

2019系统修复

修改启动顺序 尝试从最后一次正确配置启动 然后删除最后安全的程序。 准备usb系统盘 用系统引导盘进入命令提示符 chkdsk c: 在只读模式看下是否磁盘有问题。 sfc /scannow命令 在管理员命令提示符窗口输入&#xff1a;sfc /scannow命令。 复制&#xff1a;sfc /scanno…

LeetCode 746. 使用最小花费爬楼梯

一、题目 1、题目描述 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花…

倚力未来:人工智能智能辅助医疗的前景与挑战

导言 人工智能在医疗领域的应用正迅速发展&#xff0c;为医疗行业带来了新的可能性。本文将深入探讨人工智能在医疗中的智能辅助应用&#xff0c;以及这一趋势面临的前景和挑战。智慧医疗是指通过先进的信息技术&#xff0c;如人工智能、物联网、大数据等&#xff0c;实现医疗数…

使用Pytorch从零开始构建StyleGAN2

这篇博文是关于 StyleGAN2 的&#xff0c;来自论文Analyzing and Improving the Image Quality of StyleGAN&#xff0c;我们将使用 PyTorch 对其进行干净、简单且可读的实现&#xff0c;并尝试尽可能地还原原始论文。 如果您没有阅读 StyleGAN2 论文。或者不知道它是如何工作…

算法leetcode|93. 复原 IP 地址(多语言实现)

文章目录 93. 复原 IP 地址&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 93. 复原 IP 地址&#xff1a; 有效 IP …

如何戒掉懒惰这个坏习惯?

懒惰是一个常见的坏习惯&#xff0c;它会阻碍我们的进步&#xff0c;影响我们的生活质量。然而&#xff0c;戒掉懒惰并不容易&#xff0c;需要付出一定的努力和毅力。本文将介绍几种方法来戒掉懒惰习惯&#xff0c;帮助你走上一个积极向上的道路。首先&#xff0c;认识到懒惰的…

【MATLAB】数据拟合第11期-基于粒子群迭代的拟合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 基于粒子群迭代的拟合算法是一种优化技术&#xff0c;它基于粒子群优化算法&#xff08;PSO&#xff09;的基本思想。该算法通过群体中个体之间的协作和信息共享来寻找最优解。 在基于粒…

tortoisesvn各版本下载链接

https://tortoisesvn.net 无法访问最新版本下载 TortoiseSVN download | SourceForge.net 所有版本下载 TortoiseSVN - Browse Files at SourceForge.net