1.FTP云盘介绍
FTP服务器(File Transfer Protocol Server)是在互联网上提供文件存储和访问服务的计算机,它们依照FTP协议提供服务。 FTP是File Transfer Protocol(文件传输协议)。 程序运行,服务端不断接收客户端指令,服务端可同时处理多个客户端接入并对指令作出解析,并把执行结果返回给客户端,客户端根据服务端对指令的解析并把由服务端传递过来的处理信息通过客户端呈现给客户,实现文件的各种操作。Linux网络编程实现的FTP服务器,服务器由服务端和客户端组成,具有浏览远程服务端的文件和浏览客户端本地文件,同时支持对远程服务端文件的删除,存储,归档操作处理,以及客户端对远程服务端文件的上传和下载。
2.基本功能
利用socket实现:
ls-查看服务器端文件
lls-查看客户端自己的文件
cd-切换服务的目录
lcd-切换客户端自己的目录
put-上传文件
get-下载文件
3.基本流程图
4.基本思路
服务端:
1:socket 创建服务端的套接字
2:bind 端口号和IP地址
3:listen 监听客户端的连接
4:accept 接受客户端的接入
5:read 接收客户端发送的message
6:服务端开始处理从客户端接收到的消息
7:send (write)服务端的msg到客户端
客户端:
1.socket 创建客户端的套接字,构建客户端和服务端发送和接收信息的桥梁
2.connect 连接上服务端
3.获取用户键盘输入,处理输入命令buf
4.send (write)客户端的command到服务端
5.read 服务端返回的message
/*客户端*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int change(char cmd[128])
{
if(!strcmp("ls",cmd))
{
return 1;
}
else if(!strcmp("lls",cmd))
{
return 2;
}
else if(!strcmp("g",cmd))
{
return 3;
}
else if(strstr(cmd,"cd") !=NULL)
{
return 4;
}
else if(strstr(cmd,"lcd") !=NULL)
{
return 5;
}
else if(strstr(cmd,"get") !=NULL)
{
return 6;
}
else if(strstr(cmd,"put") !=NULL)
{
return 7;
}
}
char *getbind(char cmd[128])
{
char *P;
p=(char *)malloc(128);
p=strtok(cmd," ");
p=strtok(NULL," ");
return p;
}
void getmessage(char cmd[128],int c_fd)
{
char readbuf[8000];
char *p=getbind(cmd);
read(c_fd,readbuf,8000);
int fd =open(p,O_RDWR|O_CREAT,0666);
write(fd,readbuf,strlen(readbuf));
printf("receive successful!\n");
close(fd);
memset(p,0,8000);
}
void putmeaasge(char cmd[128],int c_fd)
{
int sfd;
char *P=(char *)malloc(8000);
char *readbuf=(char *)malloc(128);
readbuf =getbind(cmd);
if(access(readbuf,F_OK) ==-1)
{
printf("no file!\n");
}
else
{
sfd =open(readbuf,O_RDWR,0666);
read(sfd,p,8000);
write(c_fd,p,strlen(p));
close(sfd);
memset(p,0,8000);
}
}
void choosecmd(char cmd[128],int c_fd)
{
int ret =change(cmd);
printf("cmd = %s,ret =%d\n",cmd,ret);
char *p=(char *)malloc(8000);
switch(ret)
{
case 1:
system("ls");
break;
case 2:
read(c_fd);
printf("%s\n",p);
memset(p,0,1024);
break;
case 3:
printf("unconnecting!\n");
write(c_fd,"away host",128);
close(c_fd);
exit(-1);
break;
case 4:
break;
case 5:
p = getbind(cmd);
chdir(p);
memset(p,0,8000);
break;
case 6:
getmessage(cmd,c_fd);
break;
case 7:
putmessage(cmd,c_fd);
break;
}
}
int main(int argc,char **argv)
{
char Writebuf[128];
char Readbuf[1024];
int c_fd;
struct sockaddr_in c_addr;
int clent;
if(argc !=3)
{
perror("argc");
exit(1);
}
c_fd =socket(AF_INET,SOCK_STREAM,0);//socket创建客户端的套接字,构建客户端与服务端发送和接收信息的桥梁
if(c_fd ==-1)
{
perror("socket");
exit(1);
}
memset(&c_addr,0,sizeof(struct sockaddr_in));
c_addr.sin_family =AF_INET;
c_addr.sin_port =htons(atio(argv[2]));
inet_aton(argv[1],&c_addr.sin_addr);
//connect
clent =sizeof(struct sockaddr_in);
if(connect(c_fd,(struct sockaddr *)&c_addr,clent)) //connect连接上服务端
{
perror("connect");
exit(1);
}
//waite send
printf("connect...");
while(1)
{
gets(Writebuf);//获取用户键盘输入,处理输入命令buf
printf("cmd:%s\n",writebuf);
write(c_fd,Writebuf,strlen(Writebuf));//send客户端的command到服务端
choosecmd(Writebuf,c_fd);
printf("-------------------cmd-----------------");
memset(Writebuf,0,strlen(Writebuf));
}
return 0;
}
/*服务端*/
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
int change(char cmd[128])
{
if(!strcmp("ls",cmd))
{
return 1;
}
else if(!strcmp("ps",cmd))
{
return 2;
}
else if(!strcmp("g",cmd))
{
return 3;
}
else if(strstr(cmd,"cd") !=NULL)
{
return 4;
}
else if(strstr(cmd,"get") !=NULL)
{
return 5;
}
else if(strstr(cmd,"put") !=NULL)
{
return 6;
}
}
char *getbind(char cmd[128]) //字符串分割函数
{
char *p;
p=(char *)malloc(128);
p =strtok(cmd," ");
p =strtok(NULL," ");
return p;
}
void putmessage(char cmd[128],int c_fd)
{
char readbuf[8000];
char *p =getbind(cmd);
read(c_fd,readbuf,8000);//read接收客户端发送的message
int fd =open(p,O_RDWR|O_CREAT,0666);
write(fd,readbuf,strlen(readbuf));//send服务端的msg到客户端
printf("receive successful!\n");
close(fd);
memset(readbuf,0,8000);
}
void choosecmd(char cmd[128],int c_fd)
{
int ret;
int sfd;
FILE *fdb;
char *readbuf =(char *)malloc(128);
char *p= (char *)malloc(8000);
char freadbuf[128];
ret =change(cmd);
switch(ret)
{
case 1:
fdb = popen("ls","r");
fread(freadbuf,sizeof(freadbuf),1,fdb);
write(c_fd,freadbuf,sizeof(freadbuf));//send服务端的msg到客户端
memset(freadbuf, 0,sizeof(freadbuf));
printf("ok\n");
break;
case 2:
system("ps");
break;
case 3:
read(c_fd,freadbuf,128);//read接收客户端发送的message
printf("%s\n",freadbuf);
exit(1);
break;
case 4:
p=getbind(cmd);
chdir(p);
memset(p,0,sizeof(p));
break;
case 5:
readbuf =getbind(cmd);
if(access(readbuf,F_OK) == -1)
{
write(c_fd,"NO file",sizeof("NO file"));
}
else
{
sfd=open(readbuf,O_RDWR,0666);
read(sfd,p,8000);//read接收客户端发送的message
write(c_fd,p,strlen(p));//send服务端的msg到客户端
close(sfd);
memset(p,0,8000);
}
break;
case 6:
putmessage(cmd,c_fd);
break;
}
}
int main(int argc,char **argv)
{
int c_fd;
int s_fd;
int nread;
char Readbuf[128];
cahr Writebuf[128];
int clen;
struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
s_fd =socket(AF_INET,SOCK_STREAM,0);//创建服务端套接字
if(s_fd ==-1)
{
perror("socket");
exit(1);
}
if(argc !=3)
{
perror("argc");
exit(1);
}
memset(&s_addr,1,sizeof(sockaddr_in));
s_addr.sin_family =AF_INET;
s_addr.sin_port =htons(atoi(argv[2]));
inet_aton(argv[1],&s_addr.sin_addr);
//bind
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(sockaddr_in));//bind端口号和IP地址
//listen
listen(s_fd,10);/*表示系统允许21(2*10+1)个客户端同时进行三次握手*/
//accept
printf("wait connecting!\n");
memset(&c_addr,0,sizeof(struct sockaddr_in));
clen =sizeof(struct sockaddr_in);
while(1)
{
c_fd=accept(s_fd,(struct sockaddr *)&c_addr,&clen));//接受客户端的接入
if(c_fd == -1)
{
perror("accept");
exit(1);
}
printf("connect success ,%s\n",inet_ntoa(c_addr.sinaddr));
//read
if(fork() == 0)
{
while(1)
{
nread=read(c_fd,Readbuf,128);//read接收客户端发送的message
choosecmd(Readbuf,c_fd);//服务的开始处理从客户端接收到的信息
memset(Readbuf,0,sizeof(Readbuf));
}
}
}
}