• tftp--实现服务器与客户端的下载与上传【转】


    转自:https://blog.csdn.net/xiaopangzi313/article/details/9122975

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaopangzi313/article/details/9122975


    项目功能:实现服务器与客户端的下载与上传,及linux系统下的tftp功能

    项目名称:tftp--实现服务器与客户端的下载与上传

    开发环境:linux /C

    开发工具:GCC/GDB 

    网络协议:TCP/IP

    补充说明:程序中默认server端有upload文件夹用以接收client端上传的数据,client端有download文件夹用以下载server端的文件

    开发流程:

    编译流程:

    1.cc    server.c  -o server

    2.cc  client.c  -o client

    运行l流程:

    1.  ./server  192.168.1.207(server ip)  8888(port)

     2. ./client    192.168.1.207  8888  


    调试效果:

    client 端


    server 端

    1.server.c

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


    typedef struct {
    char cmd[10];
    int size;
    char buf[1024];
    }MSG;
    MSG msg;
    enum{list,get,put};
    int do_list(int connect_fd)
    {

    char buf[1024];
    int n;
    int fd;
    DIR *pdir;
    struct dirent *pdirent;
    if((pdir = opendir(".")) == NULL)
    {
    perror("Fail to open directory ");
    exit(EXIT_FAILURE);
    }
    while((pdirent = readdir(pdir)) != NULL)
    {
    if(pdirent->d_name[0] == '.' )
    continue;
    strcpy(msg.buf,pdirent->d_name);
    msg.size = strlen(msg.buf);
    msg.size = send(connect_fd,&msg,sizeof(MSG),0);
    }
    msg.size = 0;
    send(connect_fd,&msg,sizeof(MSG),0);
    puts("send list successfully");
    return 0;
    }


    int do_get(int connect_fd)
    {
    char filename[10];
    int n;
    int fd;
    struct stat fileinfo;
    if(recv(connect_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("fail to recv");
    exit(EXIT_FAILURE);
    }

    if(stat(msg.buf,&fileinfo) < 0)
    {
    perror("fail to stat");
    msg.size = -1;
    strcpy(msg.buf,strerror(errno));
    send(connect_fd,&msg,sizeof(MSG),0);
    return -1;
    }
    msg.size = fileinfo.st_size;
    strcpy(filename,msg.buf);


    puts("***********************");
    printf("send file size : %d ",msg.size);
    printf("send filename : %s ",msg.buf);
    puts("***********************");

    if(send(connect_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("fail to recv");
    exit(EXIT_FAILURE);
    }

    if((fd = open(msg.buf,O_RDONLY)) < 0)
    {
    fprintf(stderr,"Fail to open %s, %s ",msg.buf,strerror(errno));
    exit(EXIT_FAILURE);
    }

    while(1)
    {
    msg.size = read(fd, msg.buf,sizeof(msg.buf));
    send(connect_fd,&msg,sizeof(MSG),0);
    if(msg.size == 0)
    break;
    }
    printf("send file %s successfully ",filename);

    return 0;
    }
    int do_put(int connect_fd)
    {
    char buf[1024];
    int n;
    int fd;
    if(recv(connect_fd,&msg,sizeof(msg),0) <= 0)
    {
    perror("fail to recv");
    exit(EXIT_FAILURE);
    }

    puts("**********************************");
    printf("upload filename : %s ",msg.buf);
    printf("size: %d ",msg.size);
    puts("**********************************");

    strcpy(buf,"./upload/");
    strcat(buf,msg.buf);
    if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
    {
    perror("Fail to accept");
    exit(EXIT_FAILURE);
    }
    ftruncate(fd,msg.size);

    while(1)
    {
    recv(connect_fd,&msg,sizeof(MSG),0);
    write(fd,msg.buf,msg.size);
    if(msg.size == 0)
    break;
    }
    printf("send file successfully! ");

    exit(EXIT_SUCCESS);

    }
    int getcmd(char *pcmd)
    {
    if(strcmp(pcmd,"list") == 0)
    return 0;
    if(strcmp(pcmd,"get") == 0)
    return 1;
    if(strcmp(pcmd,"put") == 0)
    return 2;
    }
    void do_task(int connect_fd,char *cmd)
    {
    MSG msg;

    switch(getcmd(cmd))
    {
    case put:
    printf("recv file from client... ");
    do_put(connect_fd);
    break;
    case get:
    printf("send file to client... ");
    do_get(connect_fd);
    break;
    case list:
    printf("send file list to client... ");
    do_list(connect_fd);
    break;
    default :
    break;
    }

    return;
    }
    int do_client(int connect_fd)
    {
    MSG msg;
    int n;
    while(1)
    {
    if((n =recv(connect_fd,&msg,sizeof(msg),0) )< 0)
    {
    perror("fail to recv");
    exit(EXIT_FAILURE);
    }
    if(n == 0)
    break;

    do_task(connect_fd,msg.cmd);

    }

    exit(EXIT_FAILURE);
    }
    void signal_handler(int signum)
    {
    waitpid(-1,NULL,WNOHANG);
    return;
    }
    int main(int argc, const char *argv[])
    {
    pid_t pid;
    int listen_fd;
    int connect_fd;
    socklen_t addrlen;
    struct sockaddr_in peer_addr;
    struct sockaddr_in server_addr;
    if(argc < 0)
    {
    perror("fail to argc");
    exit(EXIT_FAILURE);

    }
    if(signal(SIGCHLD,signal_handler) == SIG_ERR)
    {
    perror("fail to signal");
    exit(EXIT_FAILURE);
    }
    if((listen_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
    {
    perror("fail to socket");
    exit(EXIT_FAILURE);
    }
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(atoi(argv[2]));
    server_addr.sin_addr.s_addr =inet_addr(argv[1]);
    if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) //描述本机端口和IP,要知道数据包发往哪个进程
    {
    perror("Fail to bind");
    exit(EXIT_FAILURE);
    }

    if(listen(listen_fd,8 ) < 0)//监听连接的套接字,接收各客户端的请求,返回监听套接字文件描述符
    {
    perror("Fail to listen");
    exit(EXIT_FAILURE);
    }
    puts("listening ...");
    addrlen = sizeof(peer_addr);
    while(1)
    {
    if((connect_fd = accept(listen_fd,(struct sockaddr *)&peer_addr,&addrlen)) < 0)
    {
    perror("Fail to accept");//提取客户发过来的请求,返回新的已连接的套接字文件描述符
    exit(EXIT_FAILURE);
    }
    puts("*************************");
    printf("IP : %s ",inet_ntoa(peer_addr.sin_addr));
    printf("PORT : %d ",ntohs(peer_addr.sin_port));
    puts("*************************");
    if((pid = fork()) < 0)
    {
    perror("Fail to listen");
    exit(EXIT_FAILURE);
    }
    if(pid == 0)
    {
    do_client(connect_fd);
    }
    close(connect_fd);
    }
    exit(EXIT_FAILURE);
    }


    2.client.c

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

    typedef struct {
    char cmd[10];
    int size;
    char buf[1024];
    }MSG;

    enum{list,get,put};
    int do_list(client_fd,pname)
    {
    MSG msg;
    int fd;
    while(1)
    {
    recv(client_fd,&msg,sizeof(MSG),0);
    if(msg.size == 0)
    break;
    printf("%s ",msg.buf);
    }
    puts("get list successfully");
    return 0;
    }


    int do_get(int client_fd,char *filename)
    {
    MSG msg;
    int fd;
    char buf[1024];
    strcpy(msg.buf,filename);

    if(send (client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("Fail to send");
    exit(EXIT_FAILURE);
    }

    recv(client_fd,&msg,sizeof(MSG),0);
    if(msg.size < 0)
    {
    printf("Error :%s ",msg.buf);
    return -1;
    }

    puts("***********************");
    printf(" download file size : %d ",msg.size);
    printf(" download filename : %s ",msg.buf);
    puts("***********************");

    strcpy(buf,"./download/");
    strcat(buf,msg.buf);
    if((fd = open(buf,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)
    {
    fprintf(stderr,"Fail to open %s,%s ",buf,strerror(errno));
    exit(EXIT_FAILURE);
    }

    ftruncate(fd, msg.size);

    while(1)
    {
    recv(client_fd,&msg,sizeof(MSG),0);
    if(msg.size == 0)
    break;
    write(fd,msg.buf,msg.size);
    }
    printf("download file %s successfully ",filename);
    return 0;
    }
    int do_put(int client_fd,char *filename)
    {
    MSG msg;
    int fd;
    int n;
    if((fd = open(filename,O_RDONLY)) < 0)
    {
    perror("Fail to open");
    exit(EXIT_FAILURE);

    }
    msg.size = lseek(fd,0,SEEK_END);
    strcpy(msg.buf,filename);
    lseek(fd,0,SEEK_SET);

    puts("**********************************");
    printf("filename : %s ",msg.buf);
    printf("size :%d ",msg.size);
    puts("**********************************");

    if(send(client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("Fail to send");
    exit(EXIT_FAILURE);
    }
    while(1)
    {

    msg.size = read(fd,msg.buf,sizeof(msg.buf));
    if(send(client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("Fail to read");
    exit(EXIT_FAILURE);
    }
    if(msg.size == 0)
    break;
    }
    printf("upload file successfully! ");

    return 0;
    }
    int getcmd(char *pcmd)
    {
    if(strcmp(pcmd,"list") == 0)
    return 0;
    if(strcmp(pcmd,"get") == 0)
    return 1;
    if(strcmp(pcmd,"put") == 0)
    return 2;
    }
    int do_task(char *pcmd,char *pname,int client_fd)
    {
    MSG msg;
    char buf[1024];
    int fd;
    switch(getcmd(pcmd))
    {
    case list:
    printf("get file list from the server ... ");
    strcpy(msg.cmd,pcmd);

    if(send(client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("FAIL to send");
    exit(EXIT_FAILURE);
    }
    do_list(client_fd,pname);
    break;
    case get:
    printf("file %s is downloading from server ... ",pname);
    strcpy(msg.cmd , pcmd);
    if(send(client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("FAIL to send");
    exit(EXIT_FAILURE);
    }
    do_get(client_fd,pname);
    break;
    case put:
    printf(" file %s is uploading to server ... ",pname);
    strcpy(msg.cmd,pcmd);
    if(send(client_fd,&msg,sizeof(MSG),0) < 0)
    {
    perror("Fail to send!");
    exit(EXIT_FAILURE);
    }
    do_put(client_fd,pname);
    break;

    default:
    break;

    }
    return 0;

    }
    int main(int argc, const char *argv[])
    {
    MSG msg;
    char buf[1024];
    char *pname,*pcmd;
    int client_fd;
    pid_t pid;
    int connect_fd;
    socklen_t addrlen;
    struct sockaddr_in server_addr;

    if((client_fd = socket(AF_INET,SOCK_STREAM,0) )< 0)
    {
    perror("fail to socket");
    exit(EXIT_FAILURE);
    }
    memset(&server_addr,0,sizeof(server_addr));

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


    if(connect(client_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
    {
    perror("Fail to accept");
    exit(EXIT_FAILURE);
    }

    while(1)
    {
    printf("tftp>");
    fgets(buf,sizeof(buf),stdin);
    buf[strlen(buf) -1] = '';
    if(strncmp(buf,"quit",4) == 0)
    break;
    pcmd = strtok(buf," ");
    pname = strtok(NULL," ");
    do_task(pcmd,pname,client_fd);
    }
    exit(EXIT_FAILURE);




    return 0;
    }

    ---------------------
    作者:xiaopangzi313
    来源:CSDN
    原文:https://blog.csdn.net/xiaopangzi313/article/details/9122975
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    CodeForces 1025G Company Acquisitions
    Luogu P4271 [USACO18FEB]New Barns P
    Luogu P1625 求和
    SP1772 Find The Determinant II
    CodeForces 1408G Clusterization Counting
    CodeForces 1420E Battle Lemmings
    设计模式——工厂模式
    设计模式——适配器模式
    rabbitMQ centos7 的安装
    dubbo spring 的使用
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/10783612.html
Copyright © 2020-2023  润新知