实现FTP服务

  • 服务端
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>

#define LS 0
#define PWD 1
#define CD 2
#define GET 3
#define PUT 4
#define QUIT 5
#define U_LS 6
#define U_CD 7
#define U_PWD 8
#define DOFILE 9
#define RM 10
struct Msg
{
    
    
	int num;
	char data[1024];
	char pebuf[1024];
};

char *get_set(char *msg)
{
    
    
	char *a;
	a = strtok(msg," ");//分割字符串
	a = strtok(NULL," ");
	return a;
}

int get_client_num(char *data)
{
    
    
	if(strcmp("ls",data) == 0)  return LS;//等于为0,小于为负
	if(strcmp("pwd",data) == 0)  return PWD;
	if(strstr(data,"cd") != NULL)  return CD;
	if(strstr(data,"get") != NULL)  return GET;
	if(strstr(data,"put") != NULL)  return PUT;
	if(strcmp("quit",data) == 0)  return QUIT;
	if(strstr(data,"rm") != NULL)  return RM;
	//if(strcmp("uls",data) == 0)  return U_LS;
	//if(strcmp("upwd",data) == 0)  return U_PWD;
	//if(strstr(data,"ucd") != NULL)  return U_CD;
	return 666;
}

void msg_handle(struct Msg msg,int fd)
{
    
    
	char file_buf[1024] = {
    
    0};
	FILE *z = NULL;
	printf("client request: %s\n",msg.data);
	int ret = get_client_num(msg.data);
	char *set = NULL;
	int a;
	char *request = NULL;
	switch(ret)
	{
    
    
		case LS:
		case PWD:
			msg.num = 0;
			z = popen(msg.data,"r");
			a = fread(msg.data,sizeof(msg.data),1,z);
			if(a<0){
    
    printf("error\n"); perror("fread");}
			write(fd,&msg,sizeof(msg));
			break;
			
		case CD:
			msg.num = 1;
			set = get_set(msg.data);
			printf("client set is :%s\n%s\n->",msg.data,set);
			chdir(set);
			break;

		case GET:
			request = get_set(msg.data);
			if(access(request,F_OK) == -1)
			{
    
    
				strcpy(msg.data,"no files!");
				write(fd,&msg,sizeof(msg));
			}
			else
			{
    
    
				msg.num = DOFILE;
				a = open(request,O_RDWR);
				read(a,file_buf,sizeof(file_buf));
				close(a);

				strcpy(msg.data,file_buf);
				write(fd,&msg,sizeof(msg));	
			}
			break;
		case PUT:
			fd = open(get_set(msg.data),O_RDWR|O_CREAT,0666);
			write(fd,msg.pebuf,strlen(msg.pebuf));
			close(fd);
			break;
		case RM:
			system(msg.data);
			strcpy(msg.data,"rm success...\n");
                        write(fd,&msg,sizeof(msg));
                        break;	
		case QUIT:
			printf("unconnect now!\n");
			exit(-1);
	}
}



int main(int argc , char **argv)//scoket->bind->listen->accept->read->write
{
    
    
	int on_fd;
	int pe_fd;
	int yun = sizeof(struct sockaddr_in);
	//char msg[128];
	char readbuf[128];
	int on_read;
	struct Msg msg;

	memset(readbuf,0,sizeof(readbuf));
	memset(&msg,0,sizeof(msg));

	if(argc != 3)
	{
    
    
		printf("error!\n");
		exit(-1);
	}

	on_fd = socket(AF_INET,SOCK_STREAM,0);
	if(on_fd == -1)
        {
    
    
                perror("socket");
                exit(-1);
        }

	struct sockaddr_in on_addr;
	struct sockaddr_in pe_addr;
	//struct Msg msg;

	memset(&on_addr,0,sizeof(struct sockaddr_in));
	memset(&pe_addr,0,sizeof(struct sockaddr_in));
	
	on_addr.sin_family = AF_INET;
        on_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&on_addr.sin_addr);

	bind(on_fd,(struct sockaddr *)&on_addr,sizeof(struct sockaddr_in));

	listen(on_fd,10);
	
	while(1)
	{
    
    
		pe_fd = accept(on_fd,(struct sockaddr *)&pe_addr,&yun);
		if(pe_fd == -1)
		{
    
    
			printf("connect error!\n");
			perror("accept");
		}

		printf("A new IP has connected!\nget connect:%s\n",inet_ntoa(pe_addr.sin_addr));
			
		if(fork() == 0)//创建,进入子进程
		{
    
    
			while(1)
			{
    
    
				memset(msg.data,0,sizeof(msg.data));
				on_read = read(pe_fd,&msg,sizeof(msg));
				if(on_read == -1)
				{
    
    
					printf("NO DATA\n");
					perror("read");
					break;
				}
				else if(on_read == 0)
				{
    
    
					printf("client close!\n");
					break;
        			}
				else msg_handle(msg,pe_fd);
			}
        	}
	}

	close(on_fd);
	close(pe_fd);
	return 0;
}

  • 客户端
#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
//#include <sys/stat.h>


#define LS 0
#define PWD 1
#define CD 2
#define GET 3
#define PUT 4
#define QUIT 5
#define U_LS 6
#define U_CD 7
#define U_PWD 8
#define DOFILE 9
#define RM 10

struct Msg
{
    
    
        int num;
        char data[1024];
        char pebuf[1024];
};

char *get_send(char *msg)
{
    
    
        char *a;
        a = strtok(msg," ");//分割字符串
        a = strtok(NULL," ");
        return a;
}

int get_server_num(char *data)
{
    
    
        if(strcmp("ls",data) == 0)  return LS;
        if(strcmp("pwd",data) == 0)  return PWD;
        if(strstr(data,"cd") != NULL)  return CD;
        if(strstr(data,"get") != NULL)  return GET;
        if(strstr(data,"put") != NULL)  return PUT;
        if(strcmp("quit",data) == 0)  return QUIT;
	if(strcmp("uls",data) == 0)  return U_LS;
	if(strcmp("upwd",data) == 0)  return U_PWD;
	if(strstr(data,"ucd"))  return U_CD;
	if(strstr(data,"rm") != NULL)  return RM;
        return -1;
}

int msg_handle(struct Msg msg , int fd)
{
    
    
	int ret = get_server_num(msg.data);
	char buf[128];
	char *dir = NULL;
	int fdbuf;
	int p;
	switch(ret)
	{
    
    
		case LS:
		case PWD:
		case CD:
			msg.num = 0;
			write(fd,&msg,sizeof(msg));
			break;
		case GET:
			msg.num = 1;
                     	write(fd,&msg,sizeof(msg));  

			break;
		case PUT:
			strcpy(buf,msg.data);
			dir = get_send(buf);
			if(access(dir,F_OK) == -1)
			{
    
    
				printf("%s not be\n",dir);
			}
			else
			{
    
    
				fdbuf = open(dir,O_RDWR);
				read(fdbuf,msg.pebuf,sizeof(msg.pebuf));
				close(fdbuf);

				write(fd,&msg,sizeof(msg));
			}
			break;
		case U_LS:
			//write(fd,&msg,sizeof(msg));
			system("ls");
			break;
		case U_PWD:
			//write(fd,&msg,sizeof(msg));
			system("pwd");
			break;
		case U_CD:
			//write(fd,&msg,sizeof(msg));
			dir = get_send(msg.data);
			//strcpy(msg.data,dir);
			chdir(msg.data);//改变当前工作目录
			break;
		case RM:
			free(dir);
			write(fd,&msg,sizeof(msg));
                                read(fd,&msg,sizeof(msg));
                                printf("%s",msg.data);
                                break;
		case QUIT:
			strcpy(msg.data,"client close!");
			write(fd,&msg,sizeof(msg));
			close(fd);
			exit(-1);
	}
	return ret;
}

void server_handle_deal(int fd,struct Msg msg)
{
    
    
	int pe_read;
	struct Msg msgbuf;
	int newfile;

	pe_read = read(fd,&msgbuf,sizeof(msgbuf));

	if(pe_read == 0)
	{
    
    
		printf("server error!\n");
		exit(-1);
	}
	else if(msgbuf.num == DOFILE)
	{
    
    
		char *p = get_send(msg.data);
		newfile = open(p,O_RDWR|O_CREAT,0600);
		write(newfile,msgbuf.data,strlen(msgbuf.data));
		printf("->");
	}
	else
	{
    
    
		printf("\n%s\n",msgbuf.data);
		printf("-----------------------------------\n");
		printf("->");
		//printf("-----------------------------------\n");
		//fflush(stdout);//清空输出缓冲区
	}
	
}

int main(int argc , char **argv)
{
    
    
	int pe_fd;
	struct Msg msg;
	struct sockaddr_in pe_addr;

	memset(&pe_addr,0,sizeof(struct sockaddr_in));

	if(argc != 3)
        {
    
    
                printf("error\n");
                exit(-1);
        }

	pe_addr.sin_family = AF_INET;
        pe_addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&pe_addr.sin_addr);
        pe_fd = socket(AF_INET,SOCK_STREAM,0);

	if(connect(pe_fd,(struct sockaddr *)&pe_addr,sizeof(struct sockaddr_in)) == -1)
        {
    
    
                perror("connect");
                exit(-1);
        }
	
	printf("connecting~~~~~\n");
	int ch = 0;
	int num;
	while(1)
	{
    
    
		memset(msg.data,0,sizeof(msg.data));
		if(ch == 0)
		printf("->");

		gets(msg.data);

		if(strlen(msg.data) == 0)
		{
    
    
			if(ch == 1){
    
    
			printf("->");}
			continue;
		}
		ch = 1;

		num = msg_handle(msg,pe_fd);

		if(num>LS&&num>GET&&num>PWD)
		{
    
    printf("->");
		continue;}

		if(num == -1)
		{
    
    
			printf("error! please send again!\n");
			printf("->");
			continue;
		}

		server_handle_deal(pe_fd,msg);
	}
	
	return 0;
}

后续待补充,可应用于带操作系统的板子

猜你喜欢

转载自blog.csdn.net/weixin_45824920/article/details/114164911