linux小项目FTP云盘实现
前言
这两天将之前学的linux基础知识(文件IO操作、进程、线程、网络编程、进程间通信)重新过了一遍,嗯整体来说比第一次学习对知识点的理解更加深刻了,很多之前模棱两可的概念,也有了自己的理解。俗话说:“温故而知新,可以为师矣”这些古人的说的都是很有道理的。
对于我个人学习来说,可能并不是很聪明,但是我也相信勤能补拙,所以也愿意花时间去将之前学的知识点一遍又一遍的复习,将学习到的知识点通过一个又一个的小实验进行演示,这样的学习方式对我个人来说是很有效的,确实感觉到了自己的不断进步。 对于编程学习来说,光通过看视频就想变强,可以说真的不可能,真的只能不断的敲代码,不断的制造Bug 又不断的花时间去解决最后不断的总结知识点,这样我们才能在编程道路上不断的成长。对每个新知识的学习,我自己感觉还是很有自信的,总的来说自己还是比较自律,也有明确的计划和目标,嗯,总之每天都要让自己前进一小步 加油加油。(一直都在奋斗的小殷同学)
嗯 FTP云盘这个小项目服务端和客户端加起来差不多500多行代码,当然对于其中的很多细节可能并没有处理,只是大概将功能实现了,get xxx 和 put xxx进行文件的下载和上传时还有一些小问题,不过能可以获取到我们想要的内容,后面会在优化。
提示:以下是本篇文章正文内容,下面案例可供参考
一、服务端 Server实现
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#define LS 1
#define CD 2
#define PWD 3
#define LCD 4
#define LLS 5
#define GET 6
#define PUT 7
#define QUIT 8
#define DOFILE 9
#define MAX_LISTEN 20
struct FTP
{
int type;
char databuf[1024];
char buf[1024];
char cmd[24];
};
struct FTP msg;
int get_cmd_type(char *cmd );
char *getDesDir(char *str);
void MSG_Handler(struct FTP msg,int fd);
int main(int argc,char *argv[])
{
int s_fd = 0,c_fd = 0;
int addr_len = 0;
int n_read = 0;
struct sockaddr_in s_addr,c_addr;
s_fd = socket(AF_INET,SOCK_STREAM,0);
if(s_fd == 0)
{
printf("socket error\n");
exit(-1);
}
memset(&s_addr,'0',sizeof(struct sockaddr_in));
memset(&c_addr,'0',sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
if(bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in)) == -1)
{
printf("bind error\n");
exit(-1);
}
if(listen(s_fd,MAX_LISTEN) == -1)
{
printf("listen error\n");
exit(-1);
}
addr_len = sizeof(struct sockaddr_in);
while(1)
{
static int i = 0;
c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&addr_len);
if(c_fd == -1)
{
printf("accept error\n");
exit(-1);
}
i++;
printf("connect success No %d client ip:%s port:%d\n",i,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
if(fork() == 0)
{
while(1)
{
printf("--------------------------wait cmd----------------------\n");
n_read = read(c_fd,msg.cmd,sizeof(msg.cmd));
if(n_read > 0)
{
MSG_Handler(msg,c_fd);
}
else if(n_read == 0)
{
printf("Client had quit connect\n");
exit(0);
}
else
{
printf("read error\n");
exit(-1);
}
}
}
}
close(c_fd);
close(s_fd);
return 0;
}
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;
return 100;
}
char *getDesDir(char *str)
{
char *p;
p = strtok(str," ");
p = strtok(NULL," ");
printf("p is <%s>\n",p);
return p;
}
void MSG_Handler(struct FTP msg,int fd)
{
int ret = 0;
FILE *fp = NULL;
char *file = NULL;
int ffile = 0;
int len = 0;
char buf[1024] = {0};
char *p = NULL;
ret = get_cmd_type(msg.cmd);
printf("Get cmd = %d\n",ret);
switch(ret)
{
case LS:
case PWD:
fp = popen(msg.cmd,"r");
if(NULL == fp)
{
printf("popen failed\n");
exit(-1);
}
fread(msg.databuf,sizeof(msg.databuf),1,fp);
pclose(fp);
write(fd,msg.databuf,sizeof(msg.databuf));
break;
case CD:
p = getDesDir(msg.cmd);
chdir(p);
break;
case GET:
file = getDesDir(msg.cmd);
if(access(file,F_OK) == -1)
{
strcpy(msg.databuf,"this file not exit");
write(fd,msg.databuf,sizeof(msg.databuf));
}
ffile = open(file,O_RDWR);
len = lseek(ffile,0,SEEK_END);
lseek(ffile,0,SEEK_SET);
read(ffile,buf,len);
close(ffile);
msg.type = DOFILE;
strcpy(msg.databuf,buf);
write(fd,&msg,sizeof(msg));
printf("get success\n");
break;
case QUIT:
printf("Client quit\n");
exit(-1);
break;
case PUT:
ffile = open(getDesDir(msg.cmd),O_RDWR|O_CREAT,0666);
write(ffile,msg.buf,strlen(msg.buf));
close(ffile);
default:
strcpy(buf,"cmd not exit");
write(fd,msg.databuf,sizeof(msg.databuf));
break;
}
}
二、客户端 Client 实现
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#define LS 1
#define CD 2
#define PWD 3
#define LCD 4
#define LLS 5
#define GET 6
#define PUT 7
#define QUIT 8
#define DOFILE 9
#define MAX_LISTEN 20
struct FTP
{
int type;
char databuf[1024];
char buf[1024];
char cmd[24];
};
struct FTP msg;
int get_cmd_type(char *cmd );
char *getDesDir(char *str);
int MSG_Write_Handler(struct FTP msg,int fd);
void MSG_Read_Handler(struct FTP msg,int fd);
int main(int argc,char *argv[])
{
int c_fd = 0;
int ret = 0,mark = 0;
struct sockaddr_in c_addr;
c_fd = socket(AF_INET,SOCK_STREAM,0);
if(c_fd == 0)
{
printf("socket error\n");
exit(-1);
}
memset(&c_addr,'0',sizeof(struct sockaddr_in));
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_in)) == -1)
{
printf("connect error\n");
exit(-1);
}
printf("connect success ip:%s\n",inet_ntoa(c_addr.sin_addr));
while(1)
{
if(fork() == 0)
{
while(1)
{
memset(msg.cmd,'0',sizeof(msg.cmd));
printf(">>>");
fflush(stdout);
gets(msg.cmd);
MSG_Write_Handler(msg,c_fd);
printf("---------------------send cmd done----------------\n\n");
}
}
while(1)
{
MSG_Read_Handler(msg,c_fd);
}
}
close(c_fd);
return 0;
}
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(!strcmp("lls",cmd)) return LLS;
if(!strcmp("lcd",cmd)) return LCD;
if(strstr(cmd,"cd") != NULL) return CD;
if(strstr(cmd,"get") != NULL) return GET;
if(strstr(cmd,"put") != NULL) return PUT;
return 100;
}
char *getDesDir(char *str)
{
char *p;
p = strtok(str," ");
p = strtok(NULL," ");
printf("p is <%s>\n",p);
return p;
}
int MSG_Write_Handler(struct FTP msg,int fd)
{
int ret = 0;
char *dir = NULL;
int filefd = 0;
ret = get_cmd_type(msg.cmd);
switch(ret)
{
case LS:
case PWD:
case CD:
write(fd,msg.cmd,sizeof(msg.cmd));
break;
case GET:
write(fd,msg.cmd,sizeof(msg.cmd));
break;
case LLS:
system("ls");
break;
case QUIT:
write(fd,msg.cmd,sizeof(msg.databuf));
exit(-1);
break;
case PUT:
dir = getDesDir(msg.cmd);
if(access(dir,F_OK) == 0)
{
printf("file not exit\n");
fflush(stdout);;
}
filefd = open(dir,O_RDWR);
read(filefd,msg.buf,sizeof(msg.buf));
close(filefd);
write(fd,&msg,sizeof(msg));
break;
}
}
void MSG_Read_Handler(struct FTP msg,int fd)
{
int n_read = 0;
int newfilefd = 0;
n_read = read(fd,&msg,sizeof(msg));
if(n_read == 0)
{
printf("Server Had Quit\n");
exit(0);
}
else if(msg.type == DOFILE)
{
printf("had read file1\n");
char *file = getDesDir(msg.cmd);
newfilefd = open(file,O_RDWR | O_CREAT,0666);
write(newfilefd,msg.databuf,strlen(msg.databuf));
close(newfilefd);
printf(">>>");
fflush(stdout);
}
else
{
printf("---------------------get data------------------\n");
printf("%s\n",msg.databuf);
printf("------------------------------------------------\n\n");
printf(">>>");
fflush(stdout);
}
}
三、实现结果
总结
对自己学习的检验最好的方法就是做一个比较综合的小项目,查漏补缺,及时进行复习巩固。加油鸭
|