6、基于linux文件系统编程开发ftp小项目全基础功能实现

目录

config.h

server.c

client.c

client.c(美化终端输入)


config.h

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

server.c

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

#include "config.h"

int get_cmd_type(char *cmd)
{
	if(strcmp("ls",cmd) == 0)  return LS;	
	if(strcmp("pwd",cmd) == 0) return PWD;	
	if(strcmp("quit",cmd) == 0) return QUIT;	
	
	if(strstr(cmd,"cd")) 	   return CD;
	if(strstr(cmd,"get")) 	   return GET;
	if(strstr(cmd,"put"))      return PUT;

	return -1;
} 

char *get_fileName(char *cmd)
{
	char *p = NULL; 
	
	p = strtok(cmd," ");
	p = strtok(NULL," ");
	return p;
}

void cmdHandle(int fd,struct Msg msg)
{
	int fdfile;
	int ret;
	FILE *file_fd;
	FILE *file;
	char *fileName = NULL;
	char databuf[1024] = {0};

	printf("%s\n",msg.cmd);
	ret = get_cmd_type(msg.cmd);	
	
	switch(ret){
		case LS:
		case PWD:
			//pwd ls不是文件,popen() 函数 的 返回值 是一个普通的标准I/O流(也就是pwd后输出在终端的内容)
			file = popen(msg.cmd,"r");		 
			fread(&msg.cmd,sizeof(msg.cmd),1,file);			
			write(fd,&msg,sizeof(msg));			
			break;
		case CD:
			fileName = get_fileName(msg.cmd);
			printf("fileName:%s\n",fileName);
			chdir(fileName);                    //改变当前目录,只在当前页面。而system会隐形新开一个窗口
			//perror("CD OK ");
			break;
		case GET:
			fileName = get_fileName(msg.cmd);
			if(access(fileName, F_OK) == -1){
				strcpy(msg.cmd,"No this file!!!\n");
				write(fd,&msg,sizeof(msg));
                        }else{
				msg.type = 8;	
			
				fdfile = open(fileName,O_RDWR);
				read(fdfile,databuf,sizeof(databuf));
				close(fdfile);
				
				strcpy(msg.cmd,databuf);				
				write(fd,&msg,sizeof(msg));						
			}
			break;
		case PUT:
			fileName = get_fileName(msg.cmd);
			printf("fileName is :%s\n",fileName);	
		
			fdfile = open(fileName,O_RDWR|O_CREAT,0600);
			write(fdfile,msg.databuf,strlen(msg.databuf));	
		
			printf("%s\n",msg.databuf);
			printf("-----------------------------------\n");
			
			close(fdfile);
			break;		
		case QUIT:	
			printf("client out\n");
			break;
	}
	
}	

int main(int argc,char **argv)
{
	int s_fd;
	int c_fd;
	int n_read;

	struct sockaddr_in s_addr;
	struct sockaddr_in c_addr;

	struct Msg msg;

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

	if(argc != 3){
		printf("param isn't right\n");
	}

	//1.socket
	s_fd = socket(AF_INET,SOCK_STREAM,0);
	if(s_fd == -1){
		perror("socked");
		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 clen = sizeof(struct sockaddr_in);

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

		if(fork() == 0){
			while(1){
				memset(msg.cmd,0,sizeof(msg.cmd));
				n_read = read(c_fd,&msg,sizeof(msg));
				if(n_read == 0){
					printf("client out\n");
					break;
				}else if(n_read > 0){
					cmdHandle(c_fd,msg);
				}	
			}
			break;
		}	
	}
	
	close(c_fd);
	close(s_fd);
	return 0;
}

client.c

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

#include "config.h"

int get_cmd_type(char *cmd)
{
	if(strcmp("ls",cmd) == 0)  	return LS;
	if(strcmp("pwd",cmd) == 0) 	return PWD;
	if(strcmp("quit",cmd) == 0) 	return QUIT;
	
	if(strstr(cmd,"lcd")) 		return LCD; //lcd 和 cd 位置一调换就会出错,不知道为什么,有哪位老铁知道的话,麻烦教导一下。	
    if(strstr(cmd,"cd")) 		return CD;
	
	if(strstr(cmd,"lls")) 		return LLS;
	if(strstr(cmd,"get")) 		return GET;
	if(strstr(cmd,"put")) 		return PUT;
	
	return -1;
}

char *get_fileName(char *dir)
{
	char *p = NULL;	

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

int cmd_handler(struct Msg msg,int fd)
{
	int ret;
	int p_fd;
	char *fileName = NULL;
	char buf[128] = {0}; 
	
	ret = get_cmd_type(msg.cmd);	

	switch (ret){
		case LS:
		case PWD:
		case CD:
		case GET:
			write(fd,&msg,sizeof(msg));	
			break;
		case LLS:
			system("ls");
			break;
		case LCD:
			fileName = get_fileName(msg.cmd);		
			if(access(fileName, F_OK) == -1){
				printf("---------------------------------\n");
				printf("\nNO This File!\n"); 
				printf("---------------------------------\n");
			}else{
				chdir(fileName);
			}
			break;
		case PUT:
			//fileName = get_fileName(msg.cmd);
			//printf("fileName is :%s\n",fileName);
			strcpy(buf,msg.cmd);		//strtok修改了msg,cmd这里面的命令。导致服务端接收为NULL
			fileName = get_fileName(buf);

			if(access(fileName, F_OK) == -1){
                                printf("---------------------------------\n");
				printf("\nNO This File!\n");
				printf("---------------------------------\n");
                        }else{
				p_fd = open(fileName,O_RDWR);
				read(p_fd,msg.databuf,sizeof(msg.databuf));
				
				printf("%s\n",msg.databuf);

				write(fd,&msg,sizeof(msg));	
				close(p_fd);
				
				printf("put ok !!!\n");
			}
			break;
		case QUIT:
			write(fd,&msg,sizeof(msg));
			close(fd);
	
			exit(-1);
			break;
	}

	return ret;
}

void cmd_serverMsg_handler(struct Msg msg,int fd)
{
	int f_fd;
	int n_read;
	char *fileName = NULL;
	struct Msg getmsg;

	n_read = read(fd,&getmsg,sizeof(getmsg));
	if(n_read == 0){
		printf("server is quit\n");
		exit(-1);
	}

	if(getmsg.type == 8){
		printf("get server msg\n");
		
		fileName = get_fileName(msg.cmd); 
		//printf("fileName is :%s\n",fileName);
		f_fd = open(fileName,O_RDWR|O_CREAT,0600);
		write(f_fd,getmsg.cmd,strlen(getmsg.cmd));	

		printf("get server msg over\n");
		
		close(f_fd);
	}else{	
		printf("---------------------------------\n");
		printf("%s",getmsg.cmd);	
		printf("---------------------------------\n");
	}
}

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

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

	if(argc != 3){
		printf("param isn't right\n");
	}

	//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
	if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
		perror("connect");
		exit(-1);
	}
	printf("connect ..\n");

	while(1){
		memset(msg.cmd,0,sizeof(msg));
		gets(msg.cmd);

		ret = cmd_handler(msg,c_fd);
//		||ret==GET
		if(ret==CD||ret==LLS||ret==LCD||ret==PUT||ret==QUIT){        //这一步是决定cd等命令之后,不走后面的步骤
            continue;
		}

		if(ret == -1){
			printf("this command  does not exist\n");
			continue;
		}
		
		cmd_serverMsg_handler(msg,c_fd);		
	}
		
	return 0;
}

client.c(美化终端输入)

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

#include "config.h"

int get_cmd_type(char *cmd)
{
	if(strcmp("ls",cmd) == 0)  	return LS;
	if(strcmp("pwd",cmd) == 0) 	return PWD;
	if(strcmp("quit",cmd) == 0) 	return QUIT;
	
	if(strstr(cmd,"lcd")) 		return LCD; //lcd 鍜?cd 浣嶇疆涓€璋冩崲灏变細鍑洪敊锛屼笉鐭ラ亾涓轰粈涔?	if(strstr(cmd,"cd")) 		return CD;
	
	if(strstr(cmd,"lls")) 		return LLS;
	if(strstr(cmd,"get")) 		return GET;
	if(strstr(cmd,"put")) 		return PUT;
	
	return -1;
}

char *get_fileName(char *dir)
{
	char *p = NULL;	

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

int cmd_handler(struct Msg msg,int fd)
{
	int ret;
	int p_fd;
	char *fileName = NULL;
	char buf[128] = {0}; 
	
	ret = get_cmd_type(msg.cmd);	

	switch (ret){
		case LS:
		case PWD:
		case CD:
		case GET:
			write(fd,&msg,sizeof(msg));	
			break;
		case LLS:
			system("ls");
			break;
		case LCD:
			fileName = get_fileName(msg.cmd);		
			if(access(fileName, F_OK) == -1){
				printf("---------------------------------\n");
				printf("\nNO This File!\n"); 
				printf("---------------------------------\n");
			}else{
				chdir(fileName);
			}
			break;
		case PUT:
			//fileName = get_fileName(msg.cmd);
			//printf("fileName is :%s\n",fileName);
			strcpy(buf,msg.cmd);		//strtok淇敼浜唌sg,cmd杩欓噷闈㈢殑鍛戒护銆傚鑷存湇鍔$鎺ユ敹涓篘ULL	
			fileName = get_fileName(buf);

			if(access(fileName, F_OK) == -1){
                                printf("---------------------------------\n");
				printf("\nNO This File!\n");
				printf("---------------------------------\n");
                        }else{
				p_fd = open(fileName,O_RDWR);
				read(p_fd,msg.databuf,sizeof(msg.databuf));
				write(fd,&msg,sizeof(msg));	
				close(p_fd);
			}
			break;
		case QUIT:
			write(fd,&msg,sizeof(msg));
			close(fd);
	
			exit(-1);
			break;
	}

	return ret;
}

void cmd_serverMsg_handler(struct Msg msg,int fd)
{
	int f_fd;
	int n_read;
	char *fileName = NULL;
	struct Msg getmsg;

	n_read = read(fd,&getmsg,sizeof(getmsg));
	if(n_read == 0){
		printf("server is quit\n");
		exit(-1);
	}

	if(getmsg.type == 8){
		fileName = get_fileName(msg.cmd); 
		//printf("fileName is :%s\n",fileName);
		f_fd = open(fileName,O_RDWR|O_CREAT,0600);
		write(f_fd,getmsg.cmd,strlen(getmsg.cmd));	
		
		close(f_fd);
		putchar('>');
		fflush(stdout); 
	}else{	
		printf("---------------------------------\n");
		printf("%s",getmsg.cmd);	
		printf("---------------------------------\n");
		
		putchar('>');
		fflush(stdout); 
	}
}

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

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

	if(argc != 3){
		printf("param isn't right\n");
	}

	//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
	if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
		perror("connect");
		exit(-1);
	}
	printf("connect ..\n");

	int mark = 0;

	while(1){
		memset(msg.cmd,0,sizeof(msg));
		if(mark == 0) printf(">");
		
		gets(msg.cmd);

		ret = cmd_handler(msg,c_fd);
		if(strlen(msg.cmd) == 0){
			if(mark == 1){
				printf(">");
			}
			continue;
		}

		if(ret==LLS||ret==LCD||ret==PUT||ret==QUIT){        //杩欎竴姝ユ槸鍐冲畾cd绛夊懡浠や箣鍚?涓嶈蛋鍚庨潰鐨勬楠?			
            putchar('>');
			fflush(stdout);
			continue;
		}

		mark =1;

		if(ret == -1){
			printf("this command  does not exist\n");
			printf(">");
			fflush(stdout);
			continue;
		}
		
		cmd_serverMsg_handler(msg,c_fd);		
	}
		
	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枕上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值