**
**ftp文件服务站:(实现服务端的路径查看,cd指令,服务端和客户端的当前路径文件查看,上传(put),下载(get),quit(退出客户端))
**
在Ubuntu 12上编写的代码:
头文件:
#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];
};
服务端:
#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"ftp.h"
char* getFilename(struct MSG msg){
char* p;
p=strtok(msg.cmd," ");
p=strtok(NULL," ");
return p;
}
int lookFor(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 clientid){
struct MSG hhmsg;
int nread;
int flag;
int returncmd;
char* p=NULL;
FILE* fp = NULL;
returncmd = lookFor(msg.cmd);
switch(returncmd){
case LS:
msg.type=0;
fp = popen(msg.cmd,"r");
//C language API streams||start and finish
nread = fread(msg.cmd,sizeof(msg.cmd),1,fp);
if(nread ==-1){
strcpy(msg.cmd,"popen error");
write(clientid,msg.cmd,sizeof(msg.cmd));
}
write(clientid,&msg,sizeof(msg));
break;
case PWD:
msg.type=4;
fp = popen(msg.cmd,"r");
nread = fread(msg.cmd,sizeof(msg.cmd),1,fp);
if(nread ==-1){
strcpy(msg.cmd,"pwd error");
write(clientid,msg.cmd,sizeof(msg.cmd));
}
write(clientid,&msg,sizeof(msg));
break;
case CD:
msg.type=1;
p = getFilename(msg);
chdir(p);
break;
case QUIT:
msg.type=8;
printf("client quit\n");
exit(-1);
break;
case PUT:
p=getFilename(msg);
flag=open(p,O_RDWR|O_CREAT,0666);
printf("file :%s\n",getFilename(msg));
write(flag,msg.text,strlen(msg.text));
close(flag);
break;
case GET:
p=getFilename(msg);
if(access(p,F_OK)!=0){
printf("not exist\n");
msg.type=2;
break;
}
msg.type=3;
printf("file :%s\n",getFilename(msg));
flag = open(p,O_RDWR);
read(flag,msg.text,sizeof(msg.text));
write(clientid,&msg,sizeof(msg));
close(flag);
break;
}
}
int main(int argc,char** argv){
//socket
int socketid = socket(AF_INET,SOCK_STREAM,0 );
if(socketid==-1){
printf("error");
}
int mark = 0;
struct sockaddr_in sockaddr;
struct sockaddr_in clientaddr;
//memset
memset(&sockaddr,0,sizeof(struct sockaddr_in));
memset(&clientaddr,0,sizeof(struct sockaddr_in));
struct MSG msg;
memset(&msg,0,sizeof(struct MSG));
sockaddr.sin_family = AF_INET;
//zi jie xu
sockaddr.sin_port = htons(atoi(argv[2]));
//ip transform
inet_aton(argv[1],&(sockaddr.sin_addr));
int size = sizeof(struct sockaddr_in);
//bind
int returnid = bind(socketid,(struct sockaddr*)&sockaddr,size);
if(returnid==-1){
perror("why");
}
int nread;
//listen
listen(socketid,5);
while(1){
//accept
int clientid = accept(socketid,(struct sockaddr*)&clientaddr,&size);
if(clientid!=-1){
printf("get connected:%s\n",inet_ntoa(clientaddr.sin_addr));
}
printf("----------------Welcome to FTP:---------\n");
if(fork()==0){
while(1){
memset(&msg,0,sizeof(struct MSG));
//read command
nread = read(clientid,&msg,sizeof(msg));
if(nread == 0){
printf("quit\n");
continue;
}
printf("client chooses the command:%s\n",msg.cmd);
//deal with the command from client
cmd_handler(msg,clientid);
}
}
/* else{
while(1){
memset(writebuff,0,128);
sprintf(cmd,"welcome No.%d\n",mark);
printf("%s\n",cmd);
printf("please input:\n");
gets(writebuff);
write(clientid,writebuff,strlen(writebuff));
}
}*/
}
close(socketid);
return 0;
}
客户端:
#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"ftp.h"
char* getFilename(struct MSG msg){
char* p;
p=strtok(msg.cmd," ");
p=strtok(NULL," ");
return p;
}
void message_handler(struct MSG msg,int clientid){
struct MSG mymsg;
int fd;
char* p=NULL;
read(clientid,&mymsg,sizeof(mymsg));
if(mymsg.type == 2){
printf("this file not exist\n");
return ;
}
else if(mymsg.type==3){
p=getFilename(msg);
fd = open(p,O_RDWR|O_CREAT,0666);
write(fd,mymsg.text,strlen(mymsg.text));
close(fd);
}
else{
printf("The thing from socket is:\n");
printf(">>>>>>\n%s",mymsg.cmd);
}
}
int lookFor(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;
}
int cmd_handler(struct MSG msg,int clientid){
char* p=NULL;
int flag;
char readbuff[128]={0};
int type;
int returncmd=lookFor(msg.cmd);
struct MSG hhmsg;
switch(returncmd){
case LS:
msg.type=0;
write(clientid,&msg,sizeof(struct MSG));
break;
case PWD:
msg.type=4;
write(clientid,&msg,sizeof(struct MSG));
break;
case QUIT:
msg.type=8;
write(clientid,&msg,sizeof(struct MSG));
close(clientid);
exit(-1);
break;
case CD:
msg.type=1;
write(clientid,&msg,sizeof(struct MSG));
break;
case LLS:
printf(">>>>\n");
system("ls");
break;
case PUT:
hhmsg=msg;
p=getFilename(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(clientid,&hhmsg,sizeof(hhmsg));
break;
case GET:
msg.type=2;
write(clientid,&msg,sizeof(msg));
break;
}
return returncmd;
}
int main(int argc,char** argv){
//client
int clientid = socket(AF_INET,SOCK_STREAM,0 );
if(clientid==-1){
printf("error");
}
struct MSG msg;
struct sockaddr_in clientaddr;
//memset
memset(&clientaddr,0,sizeof(struct sockaddr_in));
clientaddr.sin_family = AF_INET;
//zi jie xu
clientaddr.sin_port = htons(atoi(argv[2]));
//IP transform
inet_aton(argv[1],&(clientaddr.sin_addr));
int size = sizeof(struct sockaddr_in);
int hong;
//connect
int fd = connect(clientid,(struct sockaddr*)&clientaddr,size);
if(fd == 0){
printf("connect successfully\n");
}
printf("Welcome login the FTP document plantform:\n");
while(1){
printf(" \n");
printf("........................................\n");
printf("<<************************************>>\n");
printf("Please input your command: \n");
memset(&msg,0,sizeof(msg));
gets(msg.cmd);
hong = cmd_handler(msg,clientid);
if(hong==-1){
printf("command not exist\n");
continue;
}
if(hong<5&&hong!=1&&hong!=3){
message_handler(msg,clientid);
}
sleep(1);
}
close(clientid);
return 0;
}
注意在Ubuntu 18上运行使用gets()函数它会发出警告,这时候忽略他就可以了。