Socket编程实现文件的传输

来源:互联网 发布:淘宝怎么搜军刺 编辑:程序博客网 时间:2024/05/21 06:31

客户端执行方式:
./a.out src
其中src代表要进行传输的源文件,目标文件会在服务器端自动生成一个文件,并将客户端传送过来的src文件内容全部写入到服务器所建立的文件中;可以通过md5sum +文件名 的方式来查看src文件和服务器端中生成的文件的内容是否相等;

客户端:

/*************************************************************************    * File Name: client.c    * Author:    The answer    * Function:  Other            * Mail:      2412799512@qq.com     * Created Time: 2017年06月15日 星期四 18时54分22秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/socket.h>#include<arpa/inet.h>#include<netinet/in.h>#include<errno.h>#define MAXSIZE 4096#define IP "127.0.0.1"#define SERV_PORT 8000void sys_err(const char *ptr,int num){    perror(ptr);    exit(num);}int main(int argc,char **argv) {    // ./a.out src    int sockfd;    char buf[MAXSIZE];    struct sockaddr_in addr;    //建立socket套接字    sockfd = socket(AF_INET,SOCK_STREAM,0);    if(sockfd < 0)        sys_err("socket",-1);    bzero(&addr,sizeof(addr));    //初始化ip+port    addr.sin_family = AF_INET;    addr.sin_port = htons(SERV_PORT);    addr.sin_addr.s_addr = inet_addr(IP);    //connect将sockfd套接字描述符与服务器端的ip+port联系起来    if(connect(sockfd,(struct sockaddr *)&addr,sizeof(addr)) < 0)        sys_err("connect",-2);    //打开读的文件    const char *src = argv[1];    int fd = open(src,O_RDONLY);    if(fd < 0)        sys_err("open",-3);    while(1)    {        int len = read(fd,buf,sizeof(buf));        if(len == 0)            break;        int _tmp = 0;        //考虑若socket缓冲区小于len的情况,见原理图1        while(1)        {            int ret = write(sockfd,buf + _tmp, len - _tmp);            if(ret > 0 )                _tmp += ret;            if(_tmp == ret)                break;            if(ret < 0)            {                perror("write");                break;            }        }    }    close(sockfd);    return 0; }

这里写图片描述

                         图1

服务端:

/************************************************************************* * File Name: server.c * Author:    The answer * Function:  Other         * Mail:      2412799512@qq.com  * Created Time: 2017年06月15日 星期四 17时02分26秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<sys/socket.h>#include<signal.h>#include<sys/types.h>#include<fcntl.h>#include<sys/stat.h>#include<arpa/inet.h>#include<netinet/in.h>#include<unistd.h>#include<string.h>#define SERV_PORT 8000//封装出错函数void sys_err(const char *ptr,int num){    perror(ptr);    exit(num);}int main(int argc,char **argv){    signal(SIGPIPE,SIG_IGN);    int sockfd,accefd;    struct sockaddr_in seraddr,cliaddr;    socklen_t len;    bzero(&seraddr,sizeof(seraddr));    bzero(&cliaddr,sizeof(cliaddr));    //socket    sockfd = socket(AF_INET,SOCK_STREAM,0);    if(sockfd < 0)    {        sys_err("socket",-1);    }    //初始化ip地址+port端口号    seraddr.sin_family = AF_INET;    seraddr.sin_port = htons(SERV_PORT);    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);    //bind    if(bind(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)    {        sys_err("bind",-2);    }    //listen    if(listen(sockfd,128) < 0 )    {        sys_err("listen",-3);    }    //accept    while(1)    {        char buf[4096];        len = sizeof(cliaddr);        accefd = accept(sockfd,(struct sockaddr *)&cliaddr,&len);        if(accefd < 0)        {            if(errno == EINTR)  //判断阻塞等待客户端的链接;是被信号打断还是其它因素                continue;            else                sys_err("accept",-4);        }        //开始文件的读写操作        memset(buf,0x00,sizeof(buf));        int filefd = open("copy.txt",O_WRONLY |O_CREAT |O_TRUNC,0777);        while(1)        {            if(filefd < 0)                sys_err("open",-5);            int leng = read(accefd,buf,sizeof(buf));            if(leng == 0)            {                printf("Opposite have close the socket.\n");                 break; //表示文件已经读到了结尾,也意味着客户端关闭了socket            }            if(leng == -1 && errno == EINTR)                continue;            if(leng == -1 )                break; //表示出现了严重的错误            write(filefd,buf,leng);        }        //若文件的读写已经结束,则关闭文件描述符        close(filefd);        close(accefd);    }    close(sockfd);    return 0;}
原创粉丝点击