TCP文件服务器

项目要求:

基于tcp编写实现一个可以接收客户端的文件上传,下载,查看信号的服务器,
客户端通过输入“get filename”实现下载,
输入“put filename”实现上传,
输入“list”实现文件目录查看,
输入“quit”断开服务器。

服务器端

头文件(.h)

#ifndef _SERVER_H_
#define _SERVER_H_

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#define N 32
#define MAXSIZE 512
#define err_log(log)\
	do{\
	perror(log);\
	exit(1);\
	}while(0)
typedef struct sockaddr SA;

//目录文件显示
void process_list(int clientfd);
//下载文件
void process_get(int clientfd,const char *filename);
//上传文件
void process_put(int clientfd,const char *filename);

#endif

功能函数

#include "server.h"

//目录文件显示
void process_list(int clientfd)
{
    DIR *fp = opendir("./");
    if(fp == NULL)
        err_log("opendir");

    char buf[N]="";
    struct dirent *sdir = readdir(fp);
    while(sdir != NULL)
    {
        strcpy(buf,sdir->d_name);
        if(buf[0] != '.')
        {
            if(send(clientfd,buf,sizeof(buf),0) == -1)
                err_log("send");
        }
        bzero(buf,sizeof(buf));
        sdir = readdir(fp);
    }
    strcpy(buf, "finish");
    if(send(clientfd,buf,sizeof(buf),0) == -1)
        err_log("send");

    closedir(fp);
}

//文件下载
void process_get(int clientfd,const char *filename)
{
    struct stat file_size;
    char nexist[N] = "The file does not exist\n";
    char exist[N] = "loading......\n";
    char buf[MAXSIZE] = "0";
    int ret = 0,reachnum = 0,count = 0;
    int fd = open(filename,O_RDONLY);
    if(fd == -1)
    {
        send(clientfd,nexist,sizeof(nexist),0);
        return ;
    }
    else
    {
        send(clientfd,exist,sizeof(exist),0);
    }
    stat(filename,&file_size);

    while(1)
    {
        bzero(buf,sizeof(buf));
        ret = read(fd,buf,sizeof(buf));
        count++;
        send(clientfd,buf,ret,0);
        if(ret <MAXSIZE)
        {
            printf("%s||send------over\n",filename);
            break;
        }
        reachnum +=ret/file_size.st_size;
        if(count == ((file_size.st_size/sizeof(buf))/4))
            printf("%s||send------%d%%\n",filename,25);
        else if(count == ((file_size.st_size/sizeof(buf))/2))
            printf("%s||send------%d%%\n",filename,50);
        else if(count == (((file_size.st_size/sizeof(buf))/4)*3))
            printf("%s||send------%d%%\n",filename,75);
    }
    close(fd);
}

//文件上传
void process_put(int clientfd,const char *filename)
{
    char buf[MAXSIZE] = "0";
    int ret = 0;
    int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0777);
	if(fd == -1)
        err_log("open");
    while(1)
    {
        ret = recv(clientfd,buf,sizeof(buf),0);
        if(ret == -1)
            err_log("recv");
        write(fd,buf,ret);
        if(ret < MAXSIZE)
        {
            printf("%s||recv------over\n",filename);
            break;
        }
    }
    close(fd);
} 

服务器main函数

#include "server.h"

int main(int argc, const char *argv[])
{
	int serverfd,clientfd;
	struct sockaddr_in serveraddr,clientaddr;
	socklen_t len=sizeof(SA);
	bzero(&serveraddr,len);
	ssize_t bytes;
	char buf[N]={0};
	if(argc!=3)
	{
		fprintf(stderr,"User:%s IP PORT",argv[0]);
		return -1;
	}
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(atoi(argv[2]));
	serveraddr.sin_addr.s_addr=inet_addr(argv[1]);

	if((serverfd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		err_log("fail to socket");
	}
	if(bind(serverfd,(SA*)&serveraddr,len)<0)
	{
		close(serverfd);
		err_log("fail to bind");
	}
	if(listen(serverfd,15)<0)
	{
		close(serverfd);
		err_log("fail to listen");
	}
	while(1)
	{
		if((clientfd=accept(serverfd,(SA*)&clientaddr,&len))<0)
		{
			perror("fail to accept");
			continue;
		}

		bytes=recv(clientfd,buf,N,0);
		if(bytes<=0)
		{
			break;
		}
		switch(buf[0])
		{
		case 'L':
			process_list(clientfd);
			break;
		case 'G':
			process_get(clientfd,buf+2);
			break;
		case 'P':
			process_put(clientfd,buf+2);
			break;
		}
		close(clientfd);
	}
	close(serverfd);

	return 0;
}

客户端

头文件(.h)

#ifndef _CLIENT_H_
#define _CLIENT_H_

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define N 32
#define MAXSIZE 512
#define err_log(log)\
	do{\
	perror(log);\
	exit(1);\
	}while(0)
typedef struct sockaddr SA;
//文件目录显示
void do_list(struct sockaddr_in serveraddr);
//文件下载
void do_get(struct sockaddr_in serveraddr,const char *filename);
//文件上传
void do_put(struct sockaddr_in serveraddr,const char *filename);

#endif

功能函数

#include "client.h"

//文件目录显示
void do_list(struct sockaddr_in serveraddr)
{
    char buf[N] = "0";
    int ret = 0;
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
        err_log("socket");
    ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
    if(ret == -1)
        err_log("connect");
    printf("********list********\n");
    send(sockfd,"L",1,0);
    while(1)
    {
        bzero(buf,sizeof(buf));
        ret = recv(sockfd,buf,sizeof(buf),0);
        if(ret == -1)
            err_log("recv");
        if(strcmp(buf,"finish") == 0)
        {
            printf("********finish********\n");
            break;
        }
        printf("%s\n",buf);
    }
}

//文件下载
void do_get(struct sockaddr_in serveraddr,const char *filename)
{
    char namehand[N] = "G ";
    strcat(namehand,filename);
    char nexist[N] = "0";
    char buf[MAXSIZE] = "0";
    int ret = 0;
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
        err_log("socket");
    ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
    if(ret == -1)
        err_log("connect");

    send(sockfd,namehand,sizeof(namehand),0);

    if(recv(sockfd,nexist,sizeof(nexist),0) == -1)
        err_log("recv");
    if(strcmp(nexist,"The file does not exist\n") == 0)
    {
        printf("The file does not exist\n");
        return ;
    }
    int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC, 0777);
    if(fd == -1)
        err_log("open");

    while(1)
    {
        bzero(buf,sizeof(buf));
        ret = recv(sockfd,buf,sizeof(buf),0);
        if(ret == -1)
            err_log("recv");
        write(fd,buf,ret);
        if(ret < MAXSIZE)
        {
            printf("%s||recv------over\n",filename);
            break;
        }
    }
    close(fd);
}

//文件上传
void do_put(struct sockaddr_in serveraddr,const char *filename)
{   
    char namehand[N] = "P ";
    strcat(namehand,filename);
    struct stat file_size;
    char buf[MAXSIZE] = "0";
    int ret = 0,count = 0,reachnum = 0;
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
        err_log("socket");
    ret = connect(sockfd,(SA *)&serveraddr,sizeof(serveraddr));
    if(ret == -1)
        err_log("connect");

    int fd = open(filename, O_RDONLY);
    if(fd == -1)
    {
        printf("The file does not exist\n");
        return ;
    }
    stat(filename,&file_size);

    send(sockfd,namehand,sizeof(namehand),0);
    while(1)
    {
        ret = read(fd,buf,sizeof(buf));
        if(ret == -1)
            err_log("read");
        send(sockfd,buf,ret,0);
        if(ret <MAXSIZE)
        {
            printf("%s||send------over\n",filename);
            break;
        }
        reachnum +=ret/file_size.st_size;
        if(count == ((file_size.st_size/sizeof(buf))/4))
            printf("%s||send------%d%%\n",filename,25);
        else if(count == ((file_size.st_size/sizeof(buf))/2))
            printf("%s||send------%d%%\n",filename,50);
        else if(count == (((file_size.st_size/sizeof(buf))/4)*3))
            printf("%s||send------%d%%\n",filename,75);
    }

    close(fd);
} 

客户端主函数

#include "client.h"

int main(int argc, const char *argv[])
{
	char buf[N]={0};
	struct sockaddr_in serveraddr;
	socklen_t len=sizeof(SA);
	bzero(&serveraddr,len);

	if(argc!=3)
	{
		fprintf(stderr,"User:%s IP PORT",argv[0]);
		return 0;
	}
	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("1.list   2.get filename  3.put filename  4.quit");
		puts("***********************************************");
		puts("input cmd>>>");
		fgets(buf,N,stdin);
		buf[strlen(buf)-1]='\0';
		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;
		case 'q':
			exit(0);
			break;
		default:
			puts("cmd error");
			break;
		}

	}
	return 0;
}

如有不足,望指正,谢谢!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值