Linux--FTP服务器功能--项目

一个子进程负责一条连接通道

一、项目要求:实现以下内容

客户端支持的指令:
远程控制:

    1、获取服务器当前路径的文件:get  xxx2、 展示服务器有哪些文件:ls3、进入服务器某文件夹 :cd  xxx4、上传文件到服务器: put xxx

本地控制:

    1、查看本地客户端文件 :lls2、查看进入客户端文件夹 :lcd 

二、步骤:

服务器:解析指令(创建子进程、对接客户端)

    1、创建套接字socket2、绑定bind ip+端口号3、listen监听while(1)调用accept4、accept接受客户端请求,返回值小于0报错①、有客户端接入调用fork创建子进程,返回值小于 0 报错;等于 0 对客户端进行交互。②、对(buf)读取出来的数据做判断(ls、get、cd、pwd)①)get:open打开文件,read文件,send文件到客户端②)ls:popen文件,fread读取文件,send发送文件到客户端
// system()调用副服务器:
在子进程中:1、接收指令2、把指令写入共享内存 + get pid3、读取结果共享内存4、读到的结果返回客户端
在副服务器中:1、读取共享内存(指令共享内存)2、发现两次指令不一样,执行结果存入结果共享内存

客户端:发指令

    1、socket创建套接字2、connect连接服务器3、连接上以后获取用户的输入,对输入的信息进行处理

三、代码实现

客户端client代码

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <config.h>
#include <sys/stat.h>
#include <fcntl.h>char * getdir(char *cmd)
{char *p;p = strtok(cmsg," ");//分割字符串,用空格分隔p = strtok(NULL," ");return p; 
}int get_cmd_type(char *cmd)
{if(strstr(cmd,"lcd")!=NULL)		return LCD;if(!strcmp("lls",cmd))			return LLS;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 -1;
}int cmd_handler(struct Msg msg,int fd)
{char *dir = NULL;char buf[32];int ret;int filefd;ret = get_cmd_type(msg.data);switch(ret){case LS:case CD:case PWD:msg.type = 0;write(fd,&msg,sizeof(msg));break;case GET:msg.type = 2;write(fd,&msg,sizeof(msg));break;case PUT:strcpy(buf,msg.data);dir = getdir(buf);if(access(dir,F_OK == -1)){printf("%s No exsit !",dir);}else{fdfile = open(dir,O_RDWR);read(filefd,msg.secondBuf,sizeof(msg.secondBuf));close(filefd);write(fd,&msg,sizeof(msg));}break;case LLS:system("ls");break;case LCD:dir = getdir(msg.data);chdir(dir);break;case QUIT:strcpy(msg.data,"quit");write(fd,&msg,sizeof(msg));close(fd);exit(-1);}return ret;
}void handler_server_message(int c_fd,struct Msg msg)
{int n_read;struct Msg msg;int newfilefd;n_read = read(c_fd,&msgget,sizeof(msgget));if(n_read == 0){printf("server is out,quit \n");exit(-1);}else if(msgget.type == DOFILE){char *p = getdir(msg.data);newfilefd = open(p,O_RDWR|O_CREAT,0666);write(newfilefd,msgget,strlen(msgget));putchar(">");fflush(stdout);}else{printf("......................\n");printf("\n %s \n",msgget.data);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("param is not good");	//参数不好exit(-1);}//1、创建套接字 socketc_fd = socket(AF_INET,SOCK_STREAM,0);//用到IPV4,TCP协议,0自动配合起来if(c_fd == -1){						//返回-1,错误perror("socket");exit(-1);}c_addr.sin_family = AF_INET;	//协议族c_addr.sin_port = htons(atoi(argv[2]));	//端口号,一般为5000--9000//电脑为x86是小端字节序,网络字节序为大端字节序。所以要进行转换用htonsinet_aton(argv[1],&c_addr.sin_addr);//把字符串形式的127.0.0.1转换成网络能识别的格式。用 到inet_aton//2、connect 连接客户端的listenif(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr)) == -1){perror("connect");exit(-1);}printf("connect ....\n");//printf("get connect : %s\n",inet_ntoa(c_addr.sin_addr));//把网络格式的IP转换为字符格式int mark = 0;while(1){memset(msg.data,0,sizeof(msg.data));//初始化if(mark == 0)	printf(">");gets(msg.data);if(strlen(msg.data) == 0){if(mark == 1){printf(">");}continue;}mark = 1;int ret = cmd_handler(msg,c_fd);if(ret > IFGO){putchar(">");fflush(stdout);continue;}if(ret == -1){printf("command not \n");printf(">");fflush(stdout);continue;}handler_server_message(c_fd,msg);}return 0;
}

服务器代码server

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <config.h>
#include <sys/stat.h>
#include <fcntl.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 100;
}char *getDesDir(char *cmsg)
{char *p;p = strtok(cmsg," ");//分割字符串,用空格分隔p = strtok(NULL," ");return p;
}void msg_handler(struct Msg msg,int fd)
{char dataBuf[1024] = {0};char *file = NULL;int fdfile;//解析指令,把指令转换成想要的整型数printf("cmd : %s\n",msg.data);int ret = get_cmd_type(msg.data);switch(ret){case LS:case PWD:msg.type = 0;FILE *r = popen(msg.data,"r");fread(msg.data,sizeof(msg.data),1,r);write(fd,&msg,sizeof(msg));break;case CD:msg.type = 0;char *dir = getDesDir(msg.data);//分割字符串printf("dir : %s\n",dir);chdir(dir);break;case GET:file = getDesDir(msg.data);if(access(file,F_OK == -1)){strcpy(msg.data,"No this file !");write(fd,&msg,sizeof(msg));}else{msg.type = DOFILE;fdfile = open(file,O_RDWR);read(fdfile,dataBuf,sizeof(dataBuf));close(fdfile);strcpy(msg.data,dataBuf);write(fd,&msg,sizeof(msg));}break;case PUT:fdfile = open(getDesDir(msg.data),O_RDWR|O_CREAT,0666);write(fdfile,msg.secondBuf,strlen(msg.secondBuf));//buf放内容,msg.data放指令close(fdfile);break;case QUIT:printf("client quit ! \n");exit(-1);}
}int main(int argc,char **argv)//配置端口
{int s_fd;int c_fd;int n_read;char redBuf[128];struct sockaddr_in s_addr;		//定义结构体struct sockaddr_in c_addr;struct Msg msg;if(argc != 3){printf("param is not good\n");	//参数不好exit(-1);}//数据清空memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));//1、创建套接字 sockets_fd = socket(AF_INET,SOCK_STREAM,0);//用到IPV4,TCP协议,0自动配合起来if(s_fd == -1){						//返回-1,错误perror("socket");exit(-1);}//2、添加地址 bind		s_addr.sin_family = AF_INET;	//协议族s_addr.sin_port = htons(atoi(argv[2]));	//端口号,一般为5000--9000//电脑为x86是小端字节序,网络字节序为大端字节序。所以要进行转换用htonsinet_aton(argv[1],&s_addr.sin_addr);//把字符串形式的127.0.0.1转换成网络能识别的格式。用到inet_atonbind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct socket_in));//3、监听listenlisten(s_fd,10);//监听10个//4、连接 acceptint clen = sizeof(struct socket_in);while(1){c_fd = accept(s_fd,(struct sockaddr *)&c_addr ,&clen);//连接到客户端之后,后续的操作用返回值c_fd来操作if(c_fd == -1){perror("accept");}printf("get connect : %s\n",inet_ntoa(c_addr.sin_addr));//把网络格式的IP转换为字符格式//新的客户端接入,创建子进程,一个子进程负责一条连接通道if(fork() == 0){		//fock返回值=0进入子进程,>0进入父进程while(1){		memset(retmessage,0,sizeof(retmessage));//初始化
//5、readn_read = read(c_fd,&msg,sizeof(msg));if(n_read == 0){printf("client out !\n");break;}else if(n_read > 0){msg_handler(msg,c_fd);}
//6、write}}}close(c_fd);close(s_fd);return 0;
}

定义

//msg结构体#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 DOFILE	9struct Msg
{int type;char data[1024];char secondBuf[128];
};

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

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

相关文章

Neo4j深度学习

Neo4j的简介 Neo4j是用Java实现的开源NoSQL图数据库。从2003年开始开发&#xff0c;2007年正式发布第一版&#xff0c;其源码托管于GitHtb。Neo4j作为图数据库中的代表产品&#xff0c;已经在众多的行业项目中进行了应用&#xff0c;如&#xff1a;网络管理、软件分析、组织和…

国内手机安装 Google Play 服务 (GMS/Google Mobile Services)

目录 1. 国内手机安装 Google Play 服务 (GMS/Google Mobile Services)1.1. 什么是 GMS1.2. 国内手机只需要安装 3 个 APP1.2.1. Google Services Framework 服务框架1.2.2. Google Play Services1.2.3. Google Play Store 应用商店 1.3. 问题1.3.1. 谷歌地图闪退 2. 小米手机 …

gorm库的Find方法引发的问题

一、问题引入&#xff1f; 笔者在学习一个项目时&#xff0c;有一个登录需求&#xff0c;在登录时需要判断用户是否存在&#xff0c;特引入了Find方法做查询&#xff0c;然后根据返回值做判断&#xff0c;没想到因为Find的特性&#xff0c;导致判断存在问题&#xff0c;不管用…

C# App.xaml.cs的一些操作

一、保证只有一个进程 1.1 关闭旧的&#xff0c;打开新的 protected override void OnStartup(StartupEventArgs e) {base.OnStartup(e);var process Process.GetProcessesByName("Dog");if (process.Count() > 1) {var list process.ToList();list.Sort((p1,p2…

DirectX12_Windows_GameDevelop_3:Direct3D的初始化

引言 查看龙书时发现&#xff0c;第四章介绍预备知识的代码不太利于学习。因为它不像是LearnOpenGL那样从头开始一步一步教你敲代码&#xff0c;导致你没有一种整体感。如果你把它当作某一块的代码进行学习&#xff0c;你跟着敲会发现&#xff0c;总有几个变量是没有定义的。这…

乌班图22.04 kubeadm简单搭建k8s集群

1. 我遇到的问题 任何部署类问题实际上对于萌新来说都不算简单&#xff0c;因为没有经验&#xff0c;这里我简单将部署的步骤和想法给大家讲述一下 2. 简单安装步骤 准备 3台标准安装的乌班图server22.04&#xff08;采用vm虚拟机安装&#xff0c;ip为192.168.50.3&#xff0…

STC89C51基础及项目第10天:LCD显示字符(非标协议外设)

1. 初识LCD1602&#xff08;233.79&#xff09; 非标协议外设 LCD1602显示 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 引脚说明 第 1 脚&#xff1a; VSS 为电源地第 2 脚&#xff1…

Spark SQL 外部数据源

1.简介 1.1 多数据源支持 Spark 支持以下六个核心数据源,同时 Spark 社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景。 - CSV - JSON - Parquet - ORC - JDBC/ODBC connections - Plain-text files 1.2 读数据格式 所有读取 API 遵循以下调用格式: // …

SpringBoot项目默认使用HikariDataSource数据库连接池修改使用Druid连接池

1.启动项目&#xff0c;查看正在使用的链接池。 2.在pom.xml文件中引入驱动 <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency> 3.在ap…

【不定期更新】什么是Linux内核

2023年10月7日&#xff0c;周日晚上 目录 硬件资源管理 进程调度 文件系统管理 设备驱动 网络功能 Linux内核中的主要网络功能 安全 系统调用接口 Linux内核提供了哪些系统调用接口&#xff1f; 总结 Linux内核是Linux操作系统的核心&#xff0c;它起到以下主要的作用…

机器视觉工程师,公司设置奖金,真的为了奖励你吗?其实和你没关系

​据说某家大厂&#xff0c;超额罚款&#xff0c;有奖有罚很正常&#xff0c;但是我觉得你罚款代理商员工就不一样了&#xff0c;把代理商当成你的员工&#xff0c;我就觉得这些大厂的脑回路有问题。 有人从来没听说过项目奖金&#xff0c;更没有奖金。那么为什么设置奖金呢&a…

数字化转型频频失败?一体化模式提供新的思考

数字化连续6年出现在政府报告中&#xff0c;从《中小企业数字化赋能专项行动方案》到《关于推进“上云用数赋智”行动》、《“十四五” 规划和 2035 年远景目标建议》、《中小企业数字化转型指南》&#xff0c;再到2023年2月《数字中国建设整体布局规划》&#xff0c;加快数字化…

Java spring boot常用注解

Spring Boot是一个基于Spring框架的开发框架&#xff0c;它简化了Spring应用的配置和部署过程&#xff0c;提供了一系列注解来帮助开发人员快速构建可靠和高效的应用程序。本文将详细介绍Spring Boot中常用的注解及其使用方法。 Spring Boot注解可以分为以下几个方面&#xff…

MM-Camera架构-ProcessCaptureRequest 流程分析

文章目录 processCaptureRequest\_3\_41.1 mDevice1.2 mDevice->ops->process\_capture\_request1.3 hardware to vendor mct\_shimlayer\_process\_event2.1 mct\_shimlayer\_handle\_parm2.2 mct\_shimlayer\_reg\_buffer processCaptureRequest_3_4 sdm660的摄像头走…

图论第2天----第1020题、第130题

# 图论第2天----第1020题、第130题 文章目录 一、第1020题--飞地的数量二、第130题--被围绕的区域 ​ 又继续开始修行&#xff0c;把图论这块补上&#xff0c;估计要个5-6天时间。 一、第1020题–飞地的数量 ​ 跟前面做的思路差不多&#xff0c;其实有另外一种思路。我这里是…

mysql5.7停止维护时间

mysql5.7将于2023年10月停止官网支持和更新&#xff1b;老项目要准备升级&#xff0c;新项目的mysql必须是mysql8.0&#xff08;2023-10&#xff09; 官方升级咨询地址 oracle官方升级咨询地址https://go.oracle.com/LP116153?elq_mid247718&sh1518132002061316121320310…

数据结构—栈、队列、链表

一、栈 Stack&#xff08;存取O(1)&#xff09; 先进后出&#xff0c;进去123&#xff0c;出来321。 基于数组&#xff1a;最后一位为栈尾&#xff0c;用于取操作。 基于链表&#xff1a;第一位为栈尾&#xff0c;用于取操作。 1.1、数组栈 /*** 基于数组实现的顺序栈&#…

波浪input输入框文字边框动画

一个input输入框的小动画,大家可以按需引入和修改 input的动画表现为,文字提示波浪动画 效果图如下 源码如下 tips: 有不懂的可以在评论区问博主 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&q…

javascript中依次输出元素并不断循环实现echarts柱图动画效果

循环来遍历数组并输出其中的元素 在JavaScript中&#xff0c;你可以使用循环来遍历数组并输出其中的元素。如果你想要依次输出6个元素并不断循环&#xff0c;可以使用如下的代码&#xff1a; let arr [/* 你的数组 */];for (let i 0; i < arr.length; i) {console.log(a…

机器学习笔记(一)

1.线性回归模型 2. 损失函数 3.梯度下降算法 多元特征的线性回归 当有多个影响因素的时候,公式可以改写为: 当有多个影响因素的时候为了方便计算,可以使用 Numpy下面的点积方法, np.dot(w,x) 最后再加个b 就省略了很多书写步骤,这叫做矢量化 多元回归的梯度下降 左边是一…