TCP实现查看文件、上传、下载功能

时间:2021-01-28 23:12:56

服务器server.c:

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

#define errlog(errmsg) do{\
	perror(errmsg);\
	exit(-1);\
}while(0)
#define N 32

void do_list(int acceptfd);
void do_get(int acceptfd,char *filename);
void do_put(int acceptfd,char *filename);

int main(int argc, const char *argv[])
{
	int sockfd,acceptfd;
	struct sockaddr_in serveraddr,clientaddr;
	socklen_t addrlen = sizeof(serveraddr);
	char buf[N] = {};
	int ret;

	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		errlog("fail to socket");
	}

	if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
	{
		errlog("fail to bind");
	}

	if(listen(sockfd,5) < 0)
	{
		errlog("fail to listen");
	}

	while(1)
	{
		if((acceptfd = accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen)) < 0)
		{
			errlog("fail to accept");
		}

		ret = recv(acceptfd,buf,N,0);
		if(ret < 0)
		{
			errlog("fail to recv");
		}else if(ret == 0)
		{
			puts("%s:%d is disconnected");
			continue;
		}
		switch(buf[0])
		{
		case 'l':
			do_list(acceptfd);
			break;
		case 'g':
			do_get(acceptfd,buf + 4);
			break;
		case 'p':
			do_put(acceptfd,buf+4);
			break;
		default:
			puts("error cmd");
			break;
		}
		close(acceptfd);
	}
	return 0;
}
void do_list(int acceptfd)
{
	DIR *dp;
	struct dirent *dir;

	dp = opendir(".");
	if(dp == NULL)
	{
		errlog("fail to opendir");
	}

	while(1)
	{
		dir = readdir(dp);
		if(dir == NULL)
		{
			break;
		}
		if(strncmp(dir->d_name,".",1) == 0)
		{
			continue;
		}

		send(acceptfd,dir->d_name,N,0);
	}
}

void do_get(int acceptfd,char *filename)
{
	int fd;
	char buf[N] = {};
	int ret;

	fd = open(filename,O_RDONLY);
	if(fd < 0)
	{
		if(errno == ENOENT)
		{
			buf[0] = 'N';
			send(acceptfd,buf,N,0);
			return;
		}else{
			errlog("fail to open");
		}
	}else{
		buf[0] = 'Y';
		send(acceptfd,buf,N,0);
	}

	while(1)
	{
		ret = read(fd,buf,N);
		if(ret < 0)
		{
			errlog("fail to read");
		}else if(ret == 0)
		{
			break;
		}else{
			send(acceptfd,buf,ret,0);
		}
	}
}

void do_put(int acceptfd,char *filename)
{
	int ret;
	char buf[N] = {};
	int fd;

	fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666); //creat file
	if(fd < 0)
	{
		errlog("fail to open");
	}
	while(1)
	{
		ret = recv(acceptfd,buf,N,0);  //recv file
		if(ret < 0)
		{
			errlog("fail to upload");
		}else if(ret == 0)
		{
			puts("upload sucess!");
			break;
		}else{
			write(fd,buf,ret);
		}
	}


}


客户端client.c:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<dirent.h>
#include<fcntl.h>
#include<errno.h>
#define errlog(errmsg) do{\
						perror(errmsg);\
						exit(-1);\
						}while(0)
#define N 32

int start_up(struct sockaddr_in serveraddr);
void do_list(struct sockaddr_in serveraddr);
void do_get(struct sockaddr_in serveraddr,char *filename);
void do_put(struct sockaddr_in serveraddr,char *filename);

int main(int argc, const char *argv[])
{
	char buf[N] = {};
	int ret;

	struct sockaddr_in serveraddr;

	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);

	while(1)
	{
		puts("****************************");
		puts("*      list               * ");
		puts("*      get filename       * ");
		puts("*      put filename       * ");
		puts("****************************");
		printf("input:");
		fgets(buf,N,stdin);
		buf[strlen(buf) - 1] = '\0';
		if(strncmp(buf,"list",4) !=0 && strncmp(buf,"get ",4) !=0 && strncmp(buf,"put ",4) != 0)
		{
			puts("error cmd");
			continue;
		}

		printf("filename : %s\n",buf + 4);
		switch(buf[0])
		{
			case 'l':
				do_list(serveraddr);
				break;
			case 'g':
				do_get(serveraddr,buf + 4);
				break;
			case 'p':
				do_put(serveraddr, buf + 4);
				break;
			default:
				puts("error cmd");
				break;
		}
	}

	return 0;
}

int start_up(struct sockaddr_in serveraddr)
{
	int sockfd;
	socklen_t addrlen = sizeof(serveraddr);

	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(sockfd < 0)
	{
		errlog("fail to sockfd");
	}

	if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
	{
		errlog("fail to connect");
	}

	return sockfd;
}

void do_list(struct sockaddr_in serveraddr)
{
	int sockfd = start_up(serveraddr);
	int ret;
	char buf[N] = {};
	strcpy(buf,"list");
	send(sockfd,buf,N,0);
	while(1)
	{
		ret = recv(sockfd,buf,N,0);
		if(ret < 0)
		{
			errlog("fail to recv");
		}else if(ret == 0)
		{
			puts("LIST OVER");
			break;
		}else{
			printf("%s\n",buf);
		}
	}

}

void do_get(struct sockaddr_in serveraddr,char *filename)
{
	int sockfd = start_up(serveraddr);
	int ret;
	char buf[N] = {};
	int fd;

	strcat(strcpy(buf,"get "),filename);
	send(sockfd,buf,N,0);
	ret = recv(sockfd,buf,N,0);
	if(ret < 0)
	{
		errlog("fail to recv");
	}else if(ret == 0)
	{
		puts("the server is shutdown");
		exit(1);
	}else{
		if(strncmp(buf,"N",1) == 0)
		{
			printf("%s does not exist\n",filename);
			return;
		}
		fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666);
		if(fd < 0)
		{
			errlog("fail to open");
		}
		while(1)
		{
			ret = recv(sockfd,buf,N,0);
			if(ret < 0)
			{
				errlog("fail to recv");
			}else if(ret == 0)
			{
				puts("GET OVER");
				break;
			}else{
				write(fd,buf,ret);
			}
		}
	}


}

void do_put(struct sockaddr_in serveraddr,char *filename)	
{
	int fd;
	char buf[N]={};
	int ret;
	
	int sockfd = start_up(serveraddr);
    
	fd = open(filename,O_RDONLY);
	if(fd < 0)
	{
	 if(errno == ENOENT)
		{
			printf("%s does not exist\n",filename);
			return;
		}
		else{
			errlog("fail to open");
		}
	}else
	{
		strcat(strcpy(buf,"put "),filename);
	    send(sockfd,buf,N,0);

	    strcpy(buf,filename);
		send(sockfd,buf,N,0);	
    	while(1)
		{
			ret = read(fd,buf,N);
			if(ret < 0)
			{
				errlog("fail to read");
			}else if(ret == 0)
			{
				puts("upload OVER");
				break;
			}else{
				send(sockfd,buf,ret,0);
			}
		}

	}
		
}