Linux 文件服务系统

项目功能: 实现了对文件的远程访问,远程传输的功能。类似于 tftp 服务器。
开发及硬件组成:Linux,pc机,arm 开发板
项目描述:实现 Linux 文件服务端的开发,Linux 客户端的开发。主要使用 Linux 系统网络编程技术,当有新客户端介入时,创建一个子进程与客户端对接,实现基本的读取文件列表,获取文件,放入文件等操作。这么设计能同时支持并管理多个客户端的接入,不会因为一个客户机的退出而对其他客户机造成影响。
功能指令
展示服务器有哪些文件-------------ls
显示当前服务器路径----------------pwd
进入服务器的某个文件夹----------cd
获取服务器的文件-------------------get
上传文件到服务器-------------------put
查看客户端本地文件----------------lls
进入客户端某个文件夹-------------lcd
显示当前客户端路径----------------lpwd
客户端从服务端断开连接--------- quit
头文件:config.h


#define LS   	0
#define PWD  	1
#define GET  	2

#define IFGO	3

#define CD 		4
#define PUT  	5
#define LLS   	6
#define LCD		7
#define LPWD 	8

#define QUIT 	9
#define DOFILE 	10

struct MSG
{
	int type;
	char data[1024];
	char secondBuf[1024];
};

服务端:ftpSever_2.c

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "config.h"

char *getDir(char *cmsg)		//取空格分开的的第二个字符串
{
	char *p;
	
	p=strtok(cmsg," ");
	p=strtok(NULL," ");
	
	return p;
}

int cmd_type(char *cmd)		//检测命令并转为相应int
{
	if(!strcmp("ls",cmd))			return LS;
	if(!strcmp("pwd",cmd))			return PWD;
	if(!strcmp("quit",cmd))			return QUIT;
	if(strstr(cmd,"cd"))			return CD;
	if(strstr(cmd,"get"))			return GET;
	if(strstr(cmd,"put"))			return PUT;
}

void msg_handler(int fd,struct MSG msg)
{
	int fdfile;
	char *p=NULL;
	char *file=NULL;
	char dataBuf[1024]={0};
	
	printf("cmd:%s\n",msg.data);	//打印命令
	int ret=cmd_type(msg.data);		//将命令转为int类型

	switch(ret)
	{	
		case LS:
		case PWD:
		{
			msg.type=0;
			FILE *file=popen(msg.data,"r");		//执行命令,返回结果
			fread(msg.data,sizeof(msg.data),1,file);	//将结果读到msg.cmd
			write(fd,&msg,sizeof(msg));		//写入客户端
		break;
		}
		
		case CD:
		{
			msg.type=1;
			char *dir=getDir(msg.data);		//获取第二个参数
			printf("dir:%s\n",dir);
			int ret_cd=chdir(dir);		//系统调用函数,同cd
			if(ret_cd==-1)
			{
				perror("chdir()");
//				strcpy(msg.data,"No such file!");
//				write(fd,&msg,sizeof(msg));
			}
		break;
		}
		
		case GET:
		{
			file=getDir(msg.data);
			
			if(access(file,F_OK)==-1)		//测试文件是否存在
			{
				strcpy(msg.data,"No such file!");
				write(fd,&msg,sizeof(msg));
			}
			else
			{
				msg.type=DOFILE;		//设置标志
				
				fdfile=open(file,O_RDWR);
				read(fdfile,dataBuf,sizeof(dataBuf));		//读文件内容
//				printf("\n%s\n",dataBuf);
				close(fdfile);
				strcpy(msg.data,file);
				strcpy(msg.secondBuf,dataBuf);
				write(fd,&msg,sizeof(msg));
//				printf("\n%s\n",msg.secondBuf);
			}
		break;
		}
			
		case PUT:
		{
			p=getDir(msg.data);
			fdfile=open(p,O_RDWR|O_CREAT,0600);
			write(fdfile,msg.secondBuf,strlen(msg.secondBuf));
			close(fdfile);
		break;
		}
		
		case QUIT:
		{
            printf("client out!\n");
            exit(-1);
        break;
		}
	}
}

int main(int argc,char **argv)
{
	//1.socket
	int s_fd;
	int c_fd;
	int n_read;
	char readBuf[128];
	char writeBuf[128]={0};
	struct MSG msg;
	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;
	
	memset(&msg,0,sizeof(struct MSG));
	memset(&s_addr,0,sizeof(struct sockaddr_in));
	memset(&c_addr,0,sizeof(struct sockaddr_in));

	if(argc!=3)
	{
		printf("param is not good!\n");
		exit(-1);
	}

	s_fd=socket(AF_INET,SOCK_STREAM,0);
	if(s_fd==-1)
	{
		perror("socket");
		exit(-1);
	}

	s_addr.sin_family=AF_INET;
	s_addr.sin_port=htons(atoi(argv[2]));
	inet_aton(argv[1],&s_addr.sin_addr);
	//2.bind
	bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
	//3.listen
	listen(s_fd,10);
	//4.accept

	//	int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);
	int addrlen=sizeof(struct sockaddr_in);

	while(1)
	{
		c_fd=accept(s_fd,(struct sockaddr *)&c_addr,&addrlen);
		if(c_fd==-1)
		{
			perror("accept");
		}

		printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));
		//5.read
		
		if(fork()==0)
		{
			while(1)
			{
				memset(msg.data,0,sizeof(msg.data));
				n_read=read(c_fd,&msg,sizeof(msg));
				if(n_read==0)
				{
					printf("client is out,qiut!\n");
					break;
				}
				else if(n_read>0)
				{
					msg_handler(c_fd,msg);
				}
			}
		}
	}
	close(s_fd);
	close(c_fd);
	return 0;
}

客户端:ftpClient_2.c

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "config.h"

char *getDir(char *cmsg)
{
	char *p;
	
	p=strtok(cmsg," ");
	p=strtok(NULL," ");
	
	return p;
}

void handler_sever_message(int c_fd,struct MSG msg)
{
	int n_read;
	int newFilefd;
	struct MSG msgget;
	
	n_read=read(c_fd,&msgget,sizeof(struct MSG));
	
//	printf("\n%s\n",msgget.data);
//	printf("%ld",sizeof(struct MSG));
	
	if(n_read==0)
	{
		printf("sever is out,quit!\n");
		exit(-1);
	}
		
	else if(msgget.type==DOFILE)
	{
//		printf("\n%s\n",p);
//		printf("%ld",sizeof(struct MSG));
//		char *p=getDir(msgget.data);
		newFilefd=open(msgget.data,O_RDWR|O_CREAT,0600);
		write(newFilefd,msgget.secondBuf,sizeof(msgget.secondBuf));
//		printf("\n%s\n",msgget.data);
		putchar('>');
		fflush(stdout);
	}
	
	else
	{
		printf("--------------------------------\n");
		printf("\n%s\n",msgget.data);
		printf("--------------------------------\n");
		
		fflush(stdout);
	}
}

int cmd_type(char *cmd)
{
	if(strstr(cmd,"lcd"))		return LCD;
	if(!strcmp("lpwd",cmd))		return LPWD;
	if(!strcmp("ls",cmd))           return LS;
	if(!strcmp("pwd",cmd))          return PWD;
	if(!strcmp("quit",cmd))		return QUIT;
	if(strstr(cmd,"cd"))		return CD;
	if(strstr(cmd,"get"))		return GET;
	if(strstr(cmd,"put"))		return PUT;
	if(!strcmp("lls",cmd))		return LLS;
	
	return -1;
}

int cmd_handler(int fd,struct MSG msg)
{
	char *p=NULL;
	char buf[64]={0};
	int filefd;

	int ret=cmd_type(msg.data);		//cmd转为int类型
	
	switch(ret)
	{
		case LS:
		case PWD:
		{
			msg.type=0;
			write(fd,&msg,sizeof(msg));	
		break;
		}
		
		case CD:
		{
			msg.type=1;
			write(fd,&msg,sizeof(msg));
		break;
		}
		
		case GET:
		{
			msg.type=2;
			write(fd,&msg,sizeof(msg));
		break;
		}
		
		case PUT:
		{
			strcpy(buf,msg.data);
			p=getDir(buf);		//获取第二个参数
			
			if(access(p,F_OK)==-1)		//判断文件是否存在
			{
				printf("%s is non-existent!\n",p);
			}
			else
			{
				filefd=open(p,O_RDWR,0600);
				read(filefd,msg.secondBuf,sizeof(msg.secondBuf));		//读文件内容
				close(filefd);
				write(fd,&msg,sizeof(msg));
			break;
			}
		}
		
		case LLS:
		{
			system("ls");
		break;
		}
		
		case LPWD:
		{
			printf("\n------------------------------------\n");
			system("pwd");
			printf("\n------------------------------------\n");
		break;
		}
		
		case LCD:
		{
			char *dir=getDir(msg.data);		//获取第二个参数
			int ret_lcd=chdir(dir);		//cd dir
			if(ret_lcd==-1)		//判断命令成与否
			{
				perror("chdir()");
			}
		break;
		}
		
		case QUIT:
        {
        	strcpy(msg.data,"quit");
       		write(fd,&msg,sizeof(msg));
        	close(fd);
        	exit(-1);
        break;
        }
	}
	return ret;
}

int main(int argc,char **argv)
{
	int c_fd;
	int n_read;
	int connect_fd;
	char writeBuf[128]={0};
	char readBuf[128];
	struct MSG msg;
	struct sockaddr_in c_addr;

	memset(&c_addr,0,sizeof(struct sockaddr_in));

	if(argc!=3)
	{
		printf("param is not good!");
		exit(-1);
	}

	//1.socket
	c_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.connect
	//	int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
	connect_fd=connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in));
	if(connect_fd==-1)
	{
		perror("connect");
		exit(-1);
	}
	printf("connect......\n");
	
	while(1)
	{
		memset(msg.data,0,sizeof(msg.data));
		gets(msg.data);
		int ret=cmd_handler(c_fd,msg);
		
		if(ret>IFGO)
		{
			putchar('>');
			fflush(stdout);
			continue;
		}
		
		if(ret==-1)
		{
			printf("command not!\n");
			fflush(stdout);
			continue;
		}
		
		handler_sever_message(c_fd,msg);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值