Liunx ftp云盘项目

发布时间:2021-10-29 04:51:21

项目介绍:

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

相关文档

  • potplayer--快进设置
  • python计算ema_用python计算指数移动平均
  • 带壳生松子怎么做好吃
  • Java中多个集合的交集,并集和差集
  • 三八妇女节的祝福语
  • 2018年电影上映时间表 2018年北京密云银行从业资格考试时间及科目
  • 儿童早教最美好的唐诗宋词
  • 手机分辨率高低有什么区别
  • 小学生每日心语大全
  • 2020年北京车展总结报告
  • 给妈妈的惊喜妇女节日记
  • 至情人的一封信
  • 初入职场励志新人的文章
  • 前方高能!认清大数据交易平台新骗局
  • 创业加盟项目如何选择
  • 那个黑黑的夜散文
  • 汉菜可以和鸡蛋一起吃吗?汉菜可以炒鸡蛋吗?
  • 汤显祖名言名句
  • 河北创业投资什么生意
  • 在局域网中怎么共享打印机
  • 荣耀9xpro微信视频怎么开美颜
  • Spring中的Resource接口
  • 纯化水和软水的区别
  • 北师大版五年级上册语文期中测试卷
  • 新加坡移民如何在新加坡创办公司
  • 输送怎样造句
  • 室内设计手绘的快速表现技法
  • 飞行少年播出时间飞行少年在哪儿播
  • 虚拟机安装过程遇到的一系列问题:Job for network.service failed. See 'systemctl status network.service' and 'journalc
  • 关于端午节的qq空间说说大全
  • 猜你喜欢

    电脑版