zoukankan      html  css  js  c++  java
  • TCP编程之二

    二 文件传输模型  

    util.c

     1 #include <apue.h>
     2 
     3 /**
     4  * return value:ret
     5  * ret<0          @error
     6  * ret ==0         @success
     7  * ret<len && ret>0  @socket is closed by peer
     8  */
     9 int readn(int fd,void *buf,size_t len)
    10 {
    11     int total = 0,n;
    12     while(total<len)
    13     {
    14 again:
    15         if((n = read(fd,buf+total,len-total))<0)
    16         {
    17             if(errno==EINTR)
    18                 goto again;
    19             return -1;
    20         }
    21         else if(n==0)
    22             break;
    23         total += n;
    24     }
    25     return total;
    26 }
    27 
    28 /**
    29  * return value:ret
    30  * ret<0          @error
    31  * ret>=0         @success
    32  */
    33 int writen(int fd,const void *buf,size_t len)
    34 {
    35     int total = 0,n;
    36     while(total<len)
    37     {
    38 again:
    39         if((n = write(fd,buf+total,len-total))<0)
    40         {
    41             if(errno==EINTR)
    42                 goto again;
    43             return -1;
    44         }
    45         total += n;
    46     }
    47     return 0;
    48 }

    server.c

      1 #include <apue.h>
      2 #include "common.h"
      3 #include "util.h"
      4 
      5 #define PORT 8080
      6 #define IP "192.168.5.99"
      7 #define BACKLOG 10
      8 
      9 #define FILENAME "passwd"
     10 
     11 void *routine(void *arg);
     12 void do_business();
     13 
     14 int main(int argc, char **argv)
     15 {
     16     int sockfd;
     17     //1.创建socket
     18     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
     19         ERR("Socket failed");
     20 
     21 #if 0
     22     struct sockaddr_in {
     23         sa_family_t sin_family;
     24         in_port_t sin_port;
     25         struct in_addr sin_addr;
     26         unsigned char sin_zero[8];
     27     };
     28 #endif
     29     //2.给socket绑定地址
     30     struct sockaddr_in ipv4, peer;
     31     ipv4.sin_family = AF_INET;
     32     ipv4.sin_port = htons(PORT);    //NBO
     33     inet_pton(AF_INET, IP, &ipv4.sin_addr);    //NBO
     34     memset(ipv4.sin_zero, 0, sizeof(ipv4.sin_zero));
     35     if (bind(sockfd, (struct sockaddr *) &ipv4, sizeof(ipv4)) < 0)
     36         ERR("bind failed");
     37 
     38     //3.监听
     39     if (listen(sockfd, BACKLOG) < 0)
     40         ERR("listen failed");
     41 
     42     //4.接收连接
     43     socklen_t len = sizeof(peer);    //value-result argument
     44     int connfd;
     45     for (;;) {
     46         if ((connfd = accept(sockfd, (struct sockaddr *) &peer, &len)) < 0)
     47             ERR("accept failed");
     48 
     49         unsigned short peerport = ntohs(peer.sin_port);
     50         char ipstr[] = "ddd.ddd.ddd.ddd";
     51         inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr));
     52 
     53         //5.通信
     54         char banner[255];
     55         sprintf(banner, "[%s:%d] welcome to echoserver!", ipstr,
     56             peerport);
     57         printf("Accept a new Connection: %s,%d
    ",ipstr,peerport);
     58         if(write(connfd, banner, strlen(banner)) < strlen(banner))
     59             ERR("write failed");
     60 
     61 #ifdef MODEL_THREAD
     62         pthread_t tid;
     63         if(pthread_create(&tid,NULL,routine,(void*)connfd))
     64             ERR("create thread failed");
     65 #elif MODEL_FORK
     66         pid_t pid;
     67         if((pid = fork())<0)
     68             ERR("fork failed");
     69         else if(pid==0)
     70         {
     71             close(sockfd);        //1.关闭无用描述符
     72             do_business(connfd);
     73             exit(0);            //2.显式指定退出
     74         }
     75         close(connfd);    
     76 #endif
     77     }
     78     //7.关闭服务器
     79     close(sockfd);
     80     return 0;
     81 }
     82 
     83 void do_business()
     84 {
     85     sleep(20);
     86 }
     87 
     88 void *routine(void *arg)
     89 {
     90     int n,fd,connfd = (int)arg;
     91 
     92     struct stat st;
     93     if(stat(FILENAME,&st)<0)
     94         ERR("stat failed");
     95     size_t filesize = st.st_size;
     96 
     97     //1.send filename
     98     if(writen(connfd,FILENAME,LEN_FILENAME)<0)
     99         ERR("write fialed");
    100     //2.send filesize
    101     int filesize_nbo = htonl(filesize);
    102     if(writen(connfd,&filesize_nbo,LEN_FILESIZE)<0)
    103         ERR("write failed");
    104     //3.send filecontent <loop>
    105     if((fd = open(FILENAME,O_RDONLY))<0)
    106         ERR("open failed");
    107     char buf[LEN_BUF];
    108     while(1)
    109     {
    110         if((n = read(fd,buf,LEN_BUF))<0)
    111             ERR("read failed");
    112         else if(n==0)    //EOF
    113             break;
    114         if(writen(connfd,buf,n)<0)
    115             ERR("write failed");
    116     }
    117     close(fd);
    118     close(connfd);
    119 
    120     return NULL;
    121 }

    client.c

     1 #include <apue.h>
     2 #include "common.h"
     3 #include "util.h"
     4 
     5 void do_business(int sockfd);
     6 
     7 int main(int argc,char **argv)
     8 {    
     9     //1.判断命令行
    10     if(argc!=3)
    11     {
    12         printf("Usage: %s <host> <port>
    ",argv[0]);
    13         exit(0);
    14     }
    15     char *ipstr = argv[1];
    16     unsigned short port = strtol(argv[2],NULL,10);
    17 
    18     //2.socket
    19     int sockfd;
    20     if((sockfd = socket(PF_INET,SOCK_STREAM,0))<0)
    21         ERR("socket failed");
    22 
    23     //3.connect
    24     struct sockaddr_in peer;
    25     CLEAR(peer);
    26     peer.sin_family = AF_INET;
    27     peer.sin_port = htons(port);
    28     inet_pton(AF_INET,ipstr,&peer.sin_addr);
    29     if(connect(sockfd,(struct sockaddr*)&peer,sizeof(peer))<0)
    30         ERR("connect failed");
    31 
    32     //4.交互
    33     char banner[255];
    34     int n;
    35     if((n = read(sockfd,banner,sizeof(banner)))<0)
    36         ERR("read failed");
    37     else if(n==0)
    38         goto end;
    39     banner[n] = 0;
    40     printf("%s
    ",banner);
    41 
    42     do_business(sockfd);
    43 
    44     //5.关闭
    45 end:
    46     close(sockfd);
    47 
    48     return 0;
    49 }
    50 
    51 void do_business(int sockfd)
    52 {
    53     int n;
    54     char filename[LEN_FILENAME];
    55     //1.read filename
    56     if((n=readn(sockfd,filename,LEN_FILENAME))<0)
    57         ERR("read failed");
    58     else if(n<LEN_FILENAME)
    59     {
    60         fprintf(stderr,"Connection is closed by peer!
    ");
    61         return;
    62     }
    63 
    64     //2.read filesize
    65     size_t filesize_nbo,filesize;
    66     if((n=readn(sockfd,&filesize_nbo,LEN_FILESIZE))<0)
    67         ERR("read failed");
    68     else if(n<LEN_FILESIZE)
    69     {
    70         fprintf(stderr,"Connection is closed by peer!
    ");
    71         return;
    72     }
    73     filesize = ntohl(filesize_nbo);
    74 
    75     //3.read filecontent
    76     int fd,total = 0;
    77     if((fd = open(filename,O_WRONLY|O_CREAT,0644))<0)
    78         ERR("Open file failed");
    79     char buf[LEN_BUF];
    80     while(total<filesize)
    81     {
    82         if((n=read(sockfd,buf,LEN_BUF))<0)
    83             ERR("read failed");
    84         else if(n==0)
    85         {
    86             fprintf(stderr,"Connection is closed by peer!
    ");
    87             return;
    88         }
    89         if(writen(fd,buf,n)<0)
    90             ERR("write failed");
    91         total += n;
    92     }
    93 }
  • 相关阅读:
    Flutter
    Flutter
    Flutter
    使用Sublime Text 3作为React Native的开发IDE
    新建React Native项目步骤
    【一些容易忘记的node的npm命令】【收集】
    前端异步的一种方法库:axios
    【react】兄弟组件的通信方式,传统非redux
    【js】关于闭包和匿名函数
    【js】手机浏览器端唤起app,没有app就去下载app 的方法
  • 原文地址:https://www.cnblogs.com/xiaoying1245970347/p/3791008.html
Copyright © 2011-2022 走看看