TCP ftp服务器模型 《超经典》

//header.h
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>       
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <dirent.h>

#define BUFFERSIZE 1024

typedef struct sockaddr SA;


//服务器端
#include "header.h"

void ProcessList(int connfd);
void ProcessGet(int connfd, char buf[]);
void ProcessPut(int connfd, char buf[]);

void ProcessList(int connfd)
{
	char buf[BUFFERSIZE];
	DIR *mydir;
	struct dirent *myitem;

	mydir = opendir(".");
	while ((myitem = readdir(mydir)) != NULL)
	{
		if ((strcmp(myitem->d_name, ".") == 0)
        || (strcmp(myitem->d_name, "..") == 0))
		  continue;
		strcpy(buf, myitem->d_name);
		send(connfd, buf, BUFFERSIZE, 0);
	}
	closedir(mydir);

	return;
}


void ProcessGet(int connfd, char buf[])
{
	int fd, nbyte;

	if ((fd = open(buf+1, O_RDONLY)) < 0)
	{
		fprintf(stderr, "fail to open %s : %s\n", buf+1, strerror(errno));
		buf[0] = 'N';
		send(connfd, buf, BUFFERSIZE, 0);
		return;
	}

	buf[0] = 'Y';
	send(connfd, buf, BUFFERSIZE, 0);
	while ((nbyte = read(fd, buf, BUFFERSIZE)) > 0)
	{
		send(connfd, buf, nbyte, 0);
	}
	close(fd);

	return;
}


void ProcessPut(int connfd, char buf[])
{
	int fd, nbyte;

	if ((fd = open(buf+1, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
	{
		printf("fail to create %s on server\n", buf+1);
		return;
	}

	while ((nbyte = recv(connfd, buf, BUFFERSIZE, 0)) > 0)
	{
		write(fd, buf, nbyte);
	}
	close(fd);

	return;
}


int main(int argc, char *argv[])
{
	int listenfd, connfd;
	char buf[BUFFERSIZE];
	struct sockaddr_in server_addr;

	if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		fprintf(stderr, "fail to socket : %s\n", strerror(errno));
		exit(-1);
	}
#ifdef _DEBUG_
	printf("socket is %d\n", listenfd);
#endif

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = PF_INET;
	server_addr.sin_port = htons(8888);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(listenfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
	{
		perror("fail to bind");
		exit(-1);
	}

	listen(listenfd, 5);

	while ( 1 )
	{
		if ((connfd = accept(listenfd, NULL, NULL)) < 0)//等待客户端连接
		{
			perror("fail to accept");
			break;
		}
		recv(connfd, buf, BUFFERSIZE, 0);    //第一步收到客户端的业务请求
		switch (buf[0])
		{
			case 'L' :
				ProcessList(connfd);
				break;
			case 'G' :
				ProcessGet(connfd, buf);
				break;
			case 'P' :
				ProcessPut(connfd, buf);
				break;
		}
		close(connfd);
	}

   return 0;
}

//客户端
#include "header.h"

void PrintHelp();
void ProcessList(struct sockaddr_in server_addr);
void ProcessGet(struct sockaddr_in server_addr, char command[]);
void ProcessPut(struct sockaddr_in server_addr, char command[]);

void PrintHelp()
{
	printf("help : display help info\n");
	printf("list : get file list of server\n");
	printf("get  : get <file>\n");
	printf("put  : put <file>\n");
	printf("quit : quit the client\n");

	return;
}


void ProcessList(struct sockaddr_in server_addr)
{
 	int sockfd, nbyte;
	char buf[BUFFERSIZE]; //设置成局部变量可以互不影响

	if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
	 	printf("fail to list\n");
		return;
	}

	if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
	{
		printf("fail to connect server\n");
		goto ERROR_1;
	}

	strcpy(buf, "L");       //第一步要告诉服务器客户端需要干嘛
	send(sockfd, buf, BUFFERSIZE, 0);
	while ((nbyte = recv(sockfd, buf, BUFFERSIZE, 0)) != 0) //0放送方式 通常为0
	{
		printf("%s\n", buf);
	}

ERROR_1:
	close(sockfd);

	return;
}


void ProcessGet(struct sockaddr_in server_addr, char command[])
{
	int sockfd, nbyte, fd;
	char buf[BUFFERSIZE];

	if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		printf("fail to get\n");
		return;
	}

	if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
	{
		printf("fail to connect server\n");
		goto ERROR_2;

	}

	sprintf(buf, "G%s", command+4);
	send(sockfd, buf, BUFFERSIZE, 0);
	recv(sockfd, buf, BUFFERSIZE, 0);
	if (buf[0] == 'N') // no such file
	{
		printf("No such file on server\n");
		goto ERROR_2;
	}

	if ((fd = open(command+4, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
	{
		printf("fail to create local file %s\n", command+4);
		goto ERROR_2;
	}

	while ((nbyte = recv(sockfd, buf, BUFFERSIZE, 0)) > 0)
	{
		write(fd, buf, nbyte);
	}
	close(fd);

ERROR_2:
	close(sockfd);

	return;
}


void ProcessPut(struct sockaddr_in server_addr, char command[])
{
	int sockfd, fd, nbyte;
	char buf[BUFFERSIZE];

	if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		printf("fail to get\n");
		return;
	}

	if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
	{
		printf("fail to connect server\n");
		goto ERROR_3;

	}

	if ((fd = open(command+4, O_RDONLY)) < 0)
	{
		printf("fail to open %s\n", command+4);
		goto ERROR_3;
	}
	sprintf(buf, "P%s", command+4);
	send(sockfd, buf, BUFFERSIZE, 0);

	while ((nbyte = read(fd, buf, BUFFERSIZE)) > 0)
	{
		send(sockfd, buf, nbyte, 0);
	}
	close(fd);

ERROR_3:
	close(sockfd);

	return;
}


int main(int argc, char *argv[])
{
	int sockfd, fd, nbyte;
	char command[32];
	struct sockaddr_in server_addr;

	if (argc < 3)
	{
		printf("Usage : %s <server_ip> : <port>\n", argv[0]);
		exit(-1);
	}

	// XXX:step 1  int socket(int domain, int type, int protocol);
	if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		fprintf(stderr, "fail to socket : %s\n", strerror(errno));
		exit(-1);
	}
#ifdef _DEBUG_
	printf("socket is %d\n", sockfd);
#endif

	// XXX:step 2  int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = PF_INET;
	server_addr.sin_port = htons(atoi(argv[2]));
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);
	//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	while ( 1 )
	{
		printf("<client> ");
		fgets(command, 32, stdin);
		command[strlen(command)-1] = '\0';      // overwrite the '\n'需要减一
		if (strcmp(command, "help") == 0)
		{
		   PrintHelp();
		}
		else if (strcmp(command, "list") == 0)
		{
			ProcessList(server_addr);
		}
		else if (strncmp(command, "get ", 4) == 0)
		{
			ProcessGet(server_addr, command);
		}
		else if (strncmp(command, "put ", 4) == 0)
		{
			ProcessPut(server_addr, command);
		}
		else if (strcmp(command, "quit") == 0)
		{
			printf("Bye\n");
			break;
		}
		else
		{
			printf("wrong command, 'help' for command list\n");
		}
	}

   return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值