Liunx ftp云盘项目

发布于:2021-11-30 23:13:57

项目介绍:

利用socket实现云盘的基本功能:
ls???查看服务端文件
lls???查看客户端文件
cd???切换服务端目录
lcd???切换客户端目录
put???上传文件
get???下载文件
pwd???显示路径
quit???退出


自定义一个头文件将项目所需的宏定义和结构体放在里面(注意:该头文件引用时需要使用#include" config.h"得用引号)


#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 9


struct Msg {
int type;
char cmd[1024]; //存指令
char secondbuf[128]; //存文件内容
};

服务端:

建立get_cmd_type函数对收到的指令进行变换


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")!=NULL) return CD;
if(strstr(cmd,"get")!=NULL) return GET;
if(strstr(cmd,"put")!=NULL) return PUT;

return 100;
}

ls和pwd功能实现方法相同,调用popen函数,然后调用fread读取msg.cmd的内容,在用write写入客户端显示即可


case LS:
case PWD:
msg.type = 0;
p = popen(msg.cmd,"r");
fread(msg.cmd,sizeof(msg.cmd),1,p);
write(fd,&msg,sizeof(msg));
break;

cd为切换目录,得使用chdir函数进行实现,而不能使用system否则会造成错误,在这个地方需要对切换路径名进行识别还需建立getDisDir函数获取文件名


char *getDisDir(char *csmg)
{
char *p;
p = strtok(csmg," ");
p = strtok(NULL," ");
return p;
}

case CD:
dir = getDisDir(msg.cmd);
chdir(dir);
break;

get功能从服务端下载文件到客户端,就是将文件复制到客户端,与cp指令类似


case GET:
file = getDisDir(msg.cmd);
if(access(file,F_OK)==-1){//判断文件是否存在,若不存在access返回值为-1
strcpy(msg.cmd,"Sorry no this file");
write(fd,&msg,sizeof(msg));
}
else{
msg.type = DOFILE;
//存在若存在就打开文件
fdfile = open(file,O_RDWR);
//将文件的内容读到dataBuf内
read(fdfile,dataBuf,sizeof(dataBuf));
close(fdfile);
//将dataBuf的内容复制到msg.cmd中
strcpy(msg.cmd,dataBuf);
//将所有内容全部写入客户端内
write(fd,&msg,sizeof(msg));
}
break;

put功能将客户端文件上传到服务器


case PUT:
fdfile = open(getDisDir(msg.cmd),O_RDWR|O_CREAT,0666);
write(fdfile,msg.secondbuf,strlen(msg.secondbuf));
close(fdfile);
break;

quit退出指令:


case QUIT:
printf("clint quit
");
exit(-1);

主函数内socket编程部分


int main(int argc, char **argv)
{
//1.socket
int s_fd;
int c_fd;
int n_read;
struct Msg msg;
// char *msg ="I get you connet";
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;

if(argc != 3){
printf("progam is wrong
");
}


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]));//绔???烽?瑕??htons?芥?杩??杞??
inet_aton(argv[1],&s_addr.sin_addr);//?板?瑁??api

//2.bind
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
listen(s_fd,10);

int clen = sizeof(struct sockaddr_in);
while(1){
//4.accept
c_fd =accept(s_fd,(struct sockaddr *)&c_addr,&clen);
if(c_fd == -1){
perror("accept");
}
printf("get connect is %s
",inet_ntoa(c_addr.sin_addr));//???缁??寮??IP?板?瑁?????绗?覆褰㈠?
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("clint quit
");
break;
}
else if(n_read>0){
msg_handler(msg,c_fd);

}
}
}

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

服务端整体代码


#include
#include
#include /* See NOTES */
#include
//#include 涓?etinet/in.h?茬?:浜?#include
#include
#include
#include
#include
#include
#include
#include"config.h"

//?ㄤ?cmd??浆??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")!=NULL) return CD;
if(strstr(cmd,"get")!=NULL) return GET;
if(strstr(cmd,"put")!=NULL) return PUT;

return 100;
}

char *getDisDir(char *csmg)
{
char *p;
p = strtok(csmg," ");
p = strtok(NULL," ");
return p;
}

//?ц?cmd
void msg_handler(struct Msg msg,int fd)
{
int ret;
FILE *p;
char *dir;
char *file=NULL;
int fdfile;
char dataBuf[1024]={0};

printf("cmd:%s
",msg.cmd);
ret = get_cmd_type(msg.cmd);
switch(ret){
case LS:
case PWD:
msg.type = 0;
p = popen(msg.cmd,"r");
fread(msg.cmd,sizeof(msg.cmd),1,p);
write(fd,&msg,sizeof(msg));
break;
case CD:
msg.type = 1;
dir = getDisDir(msg.cmd);
chdir(dir);
break;
case GET:
file = getDisDir(msg.cmd);
if(access(file,F_OK)==-1){
strcpy(msg.cmd,"Sorry 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.cmd,dataBuf);
write(fd,&msg,sizeof(msg));
}
break;
case PUT:
fdfile = open(getDisDir(msg.cmd),O_RDWR|O_CREAT,0666);
write(fdfile,msg.secondbuf,strlen(msg.secondbuf));
close(fdfile);
break;
case QUIT:
printf("clint quit
");
exit(-1);
}


}

int main(int argc, char **argv)
{
//1.socket
int s_fd;
int c_fd;
int n_read;
struct Msg msg;
// char *msg ="I get you connet";
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;

if(argc != 3){
printf("progam is wrong
");
}


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]));//绔???烽?瑕??htons?芥?杩??杞??
inet_aton(argv[1],&s_addr.sin_addr);//?板?瑁??api

//2.bind
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
//3.listen
listen(s_fd,10);

int clen = sizeof(struct sockaddr_in);
while(1){
//4.accept
c_fd =accept(s_fd,(struct sockaddr *)&c_addr,&clen);
if(c_fd == -1){
perror("accept");
}
printf("get connect is %s
",inet_ntoa(c_addr.sin_addr));//???缁??寮??IP?板?瑁?????绗?覆褰㈠?
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("clint quit
");
break;
}
else if(n_read>0){
msg_handler(msg,c_fd);

}
}
}

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

客户端:

在客户端中实现GET,LS,CD,PWD,的方法是一致的,只需向服务器发送指令即可,


switch(ret){
case CD:
case PWD:
case LS:
case GET:
write(fd,&msg,sizeof(msg));
break;

put功能:


case PUT:
dir = getDir(msg.cmd);
if(access(dir,F_OK)==-1){//判断文件是否存在
printf("%s this file no exit
",dir);
}
else{
fdfile=open(dir,O_RDWR);//打开文件
read(fdfile,msg.secondbuf,sizeof(msg.secondbuf));//将内容往sg.secondbu读
close(fdfile);
write(fd,&msg,sizeof(msg));
}
break;

lcd,lls quit指令:


case LCD:
dir = getDir(msg.cmd);
chdir(dir);
break;
case LLS:
system("ls");
break;
case QUIT:
strcpy(msg.cmd,"quit");
write(fd,&msg,sizeof(msg));
close(fd);
exit(-1);
}
return ret;

}
对服务器数据的处理,首先还是判断服务器是否连接,之后对get指令进行判断,剩下的功能都是直接打印客户端或者服务端的信息


void c_msg_handler(struct Msg msg,int fd)
{
int n_read;
struct Msg msgget;
int newfdfile;
char *filename;

n_read =read(fd,&msgget,sizeof(msgget));
if(n_read == 0){
printf("sever is quit
");
exit(-1);
}
else if(msgget.type == DOFILE){//在服务端进行的设计
filename=getDir(msg.cmd);
newfdfile=open(filename,O_RDWR|O_CREAT,0666);
write(newfdfile,&msgget.cmd,strlen(msgget.cmd));
close(newfdfile);
fflush(stdout);
}
else{
printf("---------------------
");
printf("%s
",msgget.cmd);
printf("---------------------
");
fflush(stdout);
}
}

服务端整体代码


#include
#include
#include /* See NOTES */
#include
//#include 涓?etinet/in.h?茬?:浜?#include
#include
#include
#include
#include
#include
#include
#include"config.h"

int get_cmd_type(char *cmd)
{
if(strcmp("lls",cmd)==0) return LLS;
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")!=NULL) return CD;
if(strstr(cmd,"get")!=NULL) return GET;
if(strstr(cmd,"put")!=NULL) return PUT;
if(strstr(cmd,"lcd")!=NULL) return LCD;

return -1;
}

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


int cmd_handler(struct Msg msg,int fd)
{
int ret;
char *dir=NULL;
int fdfile;
char buf[32];

ret = get_cmd_type(msg.cmd);
switch(ret){
case CD:
case PWD:
case LS:
case GET:
write(fd,&msg,sizeof(msg));
break;
case PUT:
strcpy(buf,msg.cmd);
dir = getDir(buf);
if(access(dir,F_OK)==-1){
printf("%s this file no exit
",dir);
}
else{
fdfile=open(dir,O_RDWR);
read(fdfile,msg.secondbuf,sizeof(msg.secondbuf));
close(fdfile);
write(fd,&msg,sizeof(msg));
}
break;
case LCD:
dir = getDir(msg.cmd);
chdir(dir);
break;
case LLS:
system("ls");
break;
case QUIT:
strcpy(msg.cmd,"quit");
write(fd,&msg,sizeof(msg));
close(fd);
exit(-1);
}
return ret;
}

void c_msg_handler(struct Msg msg,int fd)
{
int n_read;
struct Msg msgget;
int newfdfile;
char *filename;

n_read =read(fd,&msgget,sizeof(msgget));
if(n_read == 0){
printf("sever is quit
");
exit(-1);
}
else if(msgget.type == DOFILE){
filename=getDir(msg.cmd);
newfdfile=open(filename,O_RDWR|O_CREAT,0666);
write(newfdfile,&msgget.cmd,strlen(msgget.cmd));
close(newfdfile);
fflush(stdout);
}
else{
printf("---------------------
");
printf("%s
",msgget.cmd);
printf("---------------------
");
fflush(stdout);
}
}

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

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]));//绔???烽?瑕??htons?芥?杩??杞??
inet_aton(argv[1],&c_addr.sin_addr);//?板?瑁??api
//connect
if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in))==-1){
perror("connect");
exit(-1);
}
printf("connecting ...
");
while(1){
memset(msg.cmd,0,sizeof(msg.cmd));
gets(msg.cmd);
int ret = cmd_handler(msg,c_fd);

if(ret>IFGO){
continue;
}
if(ret==-1){
printf("cmd error,please put new cmd
");
continue;
}
c_msg_handler(msg,c_fd);
}
return 0;
}

相关推荐

最新更新

猜你喜欢