基于Linux网络编程和文件编程实现的FTP云盘项目

项目思路与功能实现

socket网络编程建立服务端与客户端的连接,文件编程实现客户端与服务端数据通信,客户端通过获取用户输入的命令,进行相关的命令识别和处理,服务端通过检测客户端发送的命令,执行相应的操作,并将执行命令所获得的数据发送给客户端。

get+xxx:实现客户端远程从服务器端获取文件

put+xxx:实现客户端上传文件到服务器端

cd+xxx:实现服务器切换目录的操作

lcd+xxx:实现客户端切换目录的操作

ls、pwd:实现查看服务器当前目录的操作

lls:实现查看客户端当前目录下文件

quit:实现客户端的退出操作

服务端代码

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

int get_cmd(char cmd[128])
{
	if(!strcmp("ls",cmd))          return LS;
	if(!strcmp("pwd",cmd))         return PWD;
	if(!strcmp("quit",cmd))        return QUIT;

	if(strstr(cmd,"cd")!=NULL)     return CD;
	if(strstr(cmd,"get")!=NULL)    return GET;
	if(strstr(cmd,"put")!=NULL)    return PUT;

	return -1;       
}

char *get_dir(char *cmd)//此函数用于从指令中中剥离出文件名
{
	char *p;

	p=strtok(cmd," ");
	p=strtok(NULL," ");
       
	return p;
}

void handler_msg(int fd,struct Msg msg)
{
	int ret; 
	int fdfile;
	FILE *fp;
	char readbuff[1024]={0};
	char *p=NULL;
	char *file=NULL;

	printf("->%s\n",msg.cmd);//打印客户端指令

	ret = get_cmd(msg.cmd);
       
	switch(ret){

		case LS:
		case PWD:

			fp=popen(msg.cmd,"r");
            if(fp == NULL)
			{
            	printf("popen error!\n");
            	exit(-1); 
            }  
                                            
            memset(msg.data,0,sizeof(msg.data));
			fread(msg.data,sizeof(msg.data),1,fp);
             
			write(fd,&msg,sizeof(msg));//将ls或pwd的内容写到客户端 客户端打印出msg.data内容
		    pclose(fp);

			break;
		case CD:
			p = get_dir(msg.cmd);//剥离出cd后边的指令
			chdir(p);//chdir改变当前工作目录 参数为目标目录
                     
			break;
		case GET:
			file = get_dir(msg.cmd); //剥离出get后边的指令   
                     
			if(access(file,F_OK)==-1)//如果服务端没有这个文件
			{
				strcpy(msg.data,"No such file found\n");
				write(fd,&msg,sizeof(msg));
			}else{
				fdfile=open(file,O_RDWR);
				if(read(fdfile,readbuff,sizeof(readbuff))==0)
				{
					printf("GET:read error\n");                  
                }
				close(fdfile);

				strcpy(msg.data,readbuff);
				write(fd,&msg,sizeof(msg));//将readbuff传到客户端

			}
			break;

		case PUT:
                                             
			fdfile=open(get_dir(msg.cmd),O_RDWR|O_CREAT,0666);
            if(fdfile == -1)
			{
         		printf("PUT:Open failed\n");
            	perror("open");
            }
                        
			write(fdfile,msg.data,sizeof(msg.data));//将data内容写到fdfile中
		    close(fdfile);         
            system("ls");  
			break;

		case QUIT:
			printf("client is quit\n");
            close(fd);
			exit(-1);
            printf("also quit!");                         
        	break;
	}  
        
} 

int main(int argc,char **argv)
{

	int s_fd;
	int c_fd;
	int n_read;
	struct Msg msg;

	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;

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

	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);

	bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr));

	listen(s_fd,10);


	int len = sizeof(struct sockaddr_in);

	while(1){

		c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&len);
		if(c_fd == -1)
		{
			perror("accept:");
			exit(-1);
		}
		printf("get connect%s\n",inet_ntoa(c_addr.sin_addr));

		if(fork() == 0)
		{
			while(1)
			{                            
                memset(msg.cmd,0,sizeof(msg.cmd));//清空msg.cmd
				n_read = read(c_fd,&msg,sizeof(msg));//读c_fd指向的文件 将客户端的内容放在msg中

				if(n_read == 0)
				{
				   	printf("Client Exit\n");
                    break;
				}else if(n_read > 0)
				{
					handler_msg(c_fd,msg);//操作客户端发送来的指令
				}
			}    	
		}
	}
		close(s_fd);
		close(c_fd);
		
	return 0;

}

config.h

#define QUIT   0
#define LCD    1
#define CD     2
#define LLS    3
#define PUT    4
#define DOFILE 5
#define PWD  6
#define GET 7
#define LS 8
#define IFFILE 9

struct Msg{
       int type;
 
       char cmd[128];
       char data[1024];     
};

客户端代码

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

int get_cmd(char cmd[128])
{
	if(!strcmp("ls",cmd))          return LS;
	if(!strcmp("pwd",cmd))         return PWD;
	if(!strcmp("quit",cmd))        return QUIT;
	if(!strcmp("lls",cmd))         return LLS;

	if(strstr(cmd,"lcd")!=NULL)       return LCD;
	if(strstr(cmd,"cd")!=NULL)         return CD;
	if(strstr(cmd,"get")!=NULL)        return GET;
	if(strstr(cmd,"put")!=NULL)        return PUT;

	return -1;
}

char *get_dir(char *cmd)
{
	char *p;

	p=strtok(cmd," ");
	p=strtok(NULL," ");
    
	return p;
}

int  handler_client(int fd,struct Msg msg)
{
	int ret;
	int fdfile;
	char*file;
	char *p=NULL;
	char readbuff[1024]={0};

    struct Msg put;
   	strcpy(put.cmd,msg.cmd); 

	ret = get_cmd(msg.cmd);
       
	switch(ret){

		case LLS:
            puts("---------------------\n");
			system("ls");
			break;
		case LCD:
			p = get_dir(msg.cmd);                  
			chdir(p);//chdir改变当前工作目录 参数为目标目录
			break;
		case LS:
		case PWD:
		case CD:
			write(fd,&msg,sizeof(msg));
			break;
		case GET:       
			write(fd,&msg,sizeof(msg));
			break;
		case PUT:
			file = get_dir(msg.cmd); 
  			fdfile = open(file,O_RDWR);
                                  
			read(fdfile,readbuff,sizeof(readbuff));
			close(fdfile);
            memset(put.data,0,sizeof(put.data));
			strcpy(put.data,readbuff);
			write(fd,&put,sizeof(put));//将put内容写到服务端

			break;
		case QUIT:
			write(fd,&msg,sizeof(msg));
			close(fd);
			exit(-1);
			break;
	}

	return ret;         

}

void handler_server_msg(int fd,struct Msg msg)
{

	int n_read;
	int file;
	char *p=NULL;
	struct Msg getmsg;

	n_read=read(fd,&getmsg,sizeof(getmsg));

	if(n_read == 0)
	{
		printf("client is not ok\n");
		exit(-1);
	}else if(getmsg.type == IFFILE)
	{
		p = get_dir(msg.cmd);
		file = open(p,O_RDWR|O_CREAT,0666);
		write(file,getmsg.data,sizeof(getmsg.data));     
		close(file);
		fflush(stdout);//清空输出缓冲区
	}else{
		printf("------------------------\n");

		printf("\n%s\n",getmsg.data);

		printf("------------------------\n");

        fflush(stdout);//清空输出缓冲区
	}

}


int main(int argc,char **argv)
{
	int c_fd;
	int n_read;
	struct Msg msg;    
	struct sockaddr_in c_addr;

	if(argc != 3)
	{
		printf("parameter error\n");
		exit(-1);
	}
	memset(&c_addr,0,sizeof(struct sockaddr_in));

	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);

	if(connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr)) == -1)
	{
		perror("connect");
		exit(-1);
	}

	printf("connect success ip:%s\n",inet_ntoa(c_addr.sin_addr));//打印ip

	while(1)
	{
		if(memset(msg.cmd,0,sizeof(msg.cmd))==NULL)
		{
        	printf("memset error\n");
            exit(0);   
       	}
		printf("> ");

		gets(msg.cmd);//键盘输入给cmd
              
	   	int ret =handler_client(c_fd,msg); //指令给ret
		
		if(ret<DOFILE)//如果小于5 是quit lcd cd lls put 如果大于5是pwd get ls
		{
			fflush(stdout);
			continue;     
		}else if(ret == -1)
		{
			printf("input error\n");
			fflush(stdout);//清空输出缓冲区
			continue;     
		}

		handler_server_msg(c_fd,msg);

	}

	close(c_fd);

	return 0;

}

运行结果

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值