基于linux的简易文件服务站

服务端编写思路

一、自定义头文件文件config.h
①宏定义各项指令
②创建结构体

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

struct MSG{
int type;
char cmd[1024];
char text[1024];
};

二、socket通道编程
①创建socket套接字
②绑定套接字bind
③监听listen
④接收套接字上连接accept
a.当连接成功后,打印此时IP地址
b.创建进程,创建while(1)循环,循环内每次重置输入指令,判断是否读取到指令,
若读取到指令,则调用msg_handler函数

三、msg_handeler函数
void msg_handler(struct Msg msg,int fd)
参数struct Msg msg为定义文件内的结构体
参数int fd为accept()是的返回值通配符,相当于与客户端之间的通信通道。
①定义一个int类型变量来表示获取的命令,即此时需要先转换字符串命令为整形数字
此处调用get_cmd_type()函数。

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

②LS(显示当前路径下的文件)和PWD(显示当前路径)
a.利用popen,fread,write函数显示指令名称.
③CD指令(cd指令后需要跟其他字符,此时需要调用字符串分割函数)

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

a.定义指针来接收文件名,并打印文件名
b.利用chidr函数来实现目录跳转
④GET(获得文件)
a.定义指针来接收文件名
b.利用access函数来判断文件是否存在.若存在则打开文件,读写文件到心得地址.
⑤PUT(上传文件)
a.定义通配符来接收打开文件
b.把数据写到结构体的数据域
c.关闭光标
⑥QUIT(关闭指令)

服务端代码

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

char* getName(struct MSG msg)
{
	char* p;
	p=strtok(msg.cmd," ");
	p=strtok(NULL," ");
	return p;

}


int get_cmd_type(char* cmd){

	if(strcmp(cmd,"quit")==0){
		return QUIT;
	}
	if(strcmp(cmd,"ls")==0){
		return LS;
	}
	if(strcmp(cmd,"pwd")==0){
		return PWD;
	}
	if(strstr(cmd,"get")!=NULL){
		return GET;
	}
	if(strstr(cmd,"cd")!=NULL){
		return CD;
	}
	if(strstr(cmd,"put")!=NULL){
		return PUT;
	}
	return -1;
}

void cmd_handler(struct MSG msg,int a_fd){
	int n_read;
	int filefd;
	int ret;
	char* p=NULL;
	FILE* F = NULL;
	
	ret = get_cmd_type(msg.cmd);
	switch(ret){
		case LS:
			msg.type=0;
			F=popen(msg.cmd,"r");
			n_read=fread(msg.cmd,sizeof(msg.cmd),1,F);
			if(n_read ==-1){
				strcpy(msg.cmd,"popen error");
				write(a_fd,msg.cmd,sizeof(msg.cmd));
			}
			write(a_fd,&msg,sizeof(msg));
			break;
		case PWD:
			msg.type=4;
			F=popen(msg.cmd,"r");
			n_read=fread(msg.cmd,sizeof(msg.cmd),1,F);
			if(n_read ==-1){
				strcpy(msg.cmd,"pwd error");
				write(a_fd,msg.cmd,sizeof(msg.cmd));
			}
			write(a_fd,&msg,sizeof(msg));
			break;
		case CD:
			msg.type=1;
			p=getName(msg);
			chdir(p);
			break;
		case QUIT:
			msg.type=8;
			printf("client quit\n");
			exit(-1);
			break;
		case PUT:
			p=getName(msg);
			filefd=open(p,O_RDWR|O_CREAT,0666);
			printf("file:%s\n",getName(msg));
			write(filefd,msg.text,strlen(msg.text));
			close(filefd);
			break;
		case GET:
			p=getName(msg);
			if(access(p,F_OK)!=0){
				printf("file not exist\n");
				msg.type=2;
				break;
			}
			msg.type=3;
			printf("file :%s\n",getName(msg));
			filefd = open(p,O_RDWR);
			read(filefd,msg.text,sizeof(msg.text));
			write(a_fd,&msg,sizeof(msg));
			close(filefd);
			break;
	}
}

int main(int argc,char** argv){
	
	int s_fd; 	//socket
	int a_fd;	//accept
	int n_read;
	int size = sizeof(struct sockaddr_in);
	struct MSG msg;
	struct sockaddr_in s_addr;
        struct sockaddr_in a_addr;
 	memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&a_addr,0,sizeof(struct sockaddr_in));
        memset(&msg,0,sizeof(struct MSG)); 

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

	//2.bind
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&(s_addr.sin_addr));
	int returnid = bind(s_fd,(struct sockaddr*)&s_addr,size);
	if(returnid==-1){
		perror("bind");
	}
	//3.listen
	listen(s_fd,10);
	
	//4.accept
	while(1){
		a_fd=accept(s_fd,(struct sockaddr*)&a_addr,&size);
		if(a_fd==-1){
			perror("accept");
		}
		else{
			printf("get connected:%s\n",inet_ntoa(a_addr.sin_addr));
		}
		printf("<---------------Welcome to FTP:--------->\n");

		if(fork()==0){
			while(1){
				memset(&msg,0,sizeof(struct MSG));
				n_read = read(a_fd,&msg,sizeof(msg));
				if(n_read == 0){
					printf("quit\n");
					continue;
				}
				printf("client chooses the command:%s\n",msg.cmd);
				cmd_handler(msg,a_fd);

			}
		}
	}
	
	close(s_fd);
	close(a_fd);
	return 0;
}

客户端编写思路

一、创建宏定义文件
①宏定义各项指令
②创建结构体
struct Msg
{
int type;
char cmd[1024]; //存放指令
char text[1024]; //存放内容
}
二、socket通道编程
①创建socket套接字
②发起连接connect
a.判断连接是否成功,若成功则打印连接
b.调用函数cmd_handler( ),对输入指令进行switch分支操作
c.不断获取用户输入命令,仅当是LS,PWD,GET时调用handler_server_message函数
三、判断指令操作cmd_handler函数
①LS,CD,PWD:显示指令
②GET:显示获得的文件
③PUT
a.将指令写在新开辟的空间中。
b.获取文件名(调用getdir函数)
c.判断文件是否存在,不存在则打印not exist,存在则进行读写操作
④LLS:直接调用system()跳转到当前
⑤LCD:调用getdir()获得文件名,再调用chdir()跳转
⑥QUIT:退出
四、handler_server_message()用来发送文件

客服端代码

#include<stdio.h>
#include <unistd.h>
#include<stdlib.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>          
#include <sys/socket.h>
//#include<linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#include"ftp.h"
char* getName(struct MSG msg)
{
	char* p;
	p=strtok(msg.cmd," ");
	p=strtok(NULL," ");
	return p;
}

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

void message_handler(struct MSG msg,int s_fd)
{
	struct MSG mymsg;
	int fd;
	char* p=NULL;
	read(s_fd,&mymsg,sizeof(mymsg));
	
	if(mymsg.type == 2){
		printf("this file not exist\n");
		return ;
	}
	else if(mymsg.type==3){
		p=getName(msg);
		fd = open(p,O_RDWR|O_CREAT,0666);
		write(fd,mymsg.text,strlen(mymsg.text));
		close(fd);
	}
	else{
		printf("\n");
		printf("The thing from socket is:\n");
		printf(">>>>\n%s",mymsg.cmd);
		printf("<<<<\n");
	}
}

int cmd_handler(struct MSG msg,int s_fd)
{
	char* p=NULL;
	int flag;
	char readbuff[128]={0};
	int type;
	int returncmd=get_cmd_type(msg.cmd);
	struct MSG hhmsg;
	switch(returncmd){
		case LS:
			msg.type=0;
			write(s_fd,&msg,sizeof(struct MSG));
			break;
		case PWD:
			msg.type=4;
			write(s_fd,&msg,sizeof(struct MSG));
			break;
		case QUIT:
			msg.type=8;
			write(s_fd,&msg,sizeof(struct MSG));
			close(s_fd);
			exit(-1);
			break;
		case CD:
			msg.type=1;
			write(s_fd,&msg,sizeof(struct MSG));
			break;
		case LLS:
			printf(">>>>\n");
			system("ls");
			break;
		case PUT:
			hhmsg=msg;
			p=getName(msg);
			if(access(p,F_OK)!=0){
				printf("the file not exist");
				break;
			}
			flag=open(p,O_RDWR);
			read(flag,hhmsg.text,sizeof(hhmsg.text));
			write(s_fd,&hhmsg,sizeof(hhmsg));
			break;
		case GET:
			msg.type=2;
			write(s_fd,&msg,sizeof(msg));
			break;


	}
	return returncmd;
}


int main(int argc,char** argv){
	
	int s_fd;
	int c_fd;
	int ret;                   //judge return define type
	struct MSG msg;
	struct sockaddr_in s_addr;	
	memset(&s_addr,0,sizeof(struct sockaddr_in));
	
	//get now time
	time_t timep;
    	struct tm *p;
    	time (&timep);
    	p=gmtime(&timep);

	//1.socket
	s_fd = socket(AF_INET,SOCK_STREAM,0 );
	if(s_fd==-1){
		perror("socket");
	}
	s_addr.sin_family = AF_INET;
	s_addr.sin_port = htons(atoi(argv[2]));
	inet_aton(argv[1],&(s_addr.sin_addr));
	
	//2.connect
	int size = sizeof(struct sockaddr_in);
	printf("                                        \n");
	c_fd =  connect(s_fd,(struct sockaddr*)&s_addr,size);
	if(c_fd== 0){
	printf("<----------connect successful----------->\n");
	}else{
		perror("connect");
	}
	printf("Welcome to the FTP file receiving station\n");
	//printf("%d\n",1900+p->tm_year);/*鑾峰彇褰撳墠骞翠唤,浠�1900寮€濮嬶紝鎵€浠ヨ鍔�1900*/
	//printf("%d\n",1+p->tm_mon);/*鑾峰彇褰撳墠鏈堜唤,鑼冨洿鏄�0-11,鎵€浠ヨ鍔�1*/
	//printf("%d\n",8+p->tm_hour);/*鑾峰彇褰撳墠鏃�,杩欓噷鑾峰彇瑗挎柟鐨勬椂闂�,鍒氬ソ鐩稿樊鍏釜灏忔椂*
	//printf("%d\n",p->tm_min); /*鑾峰彇褰撳墠鍒�*/
	printf("Login time %d-%d-%d:%d\n",1900+p->tm_year,1+p->tm_mon,8+p->tm_hour,p->tm_min);

	while(1){
		printf("........................................\n");
		printf("<<************************************>>\n");
		printf("Please input your command:");
		printf("\n");

		memset(&msg,0,sizeof(msg));
		gets(msg.cmd);
		
		ret=cmd_handler(msg,s_fd);
		if(ret==-1){
			printf("command not exist\n");
			continue;
		}
		if(ret==0 || ret==2 || ret==4){             
			message_handler(msg,s_fd);
		}
		sleep(1);
	}

	close(s_fd);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值