zoukankan      html  css  js  c++  java
  • linux下echo与time服务的程序实现

    一、针对ECHO服务的TCP客户软件的实现

    1.网络拓扑结构:

    2.源码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <unistd.h>
      4 #include <string.h>
      5 #include <stdarg.h>
      6 #include <sys/types.h>
      7 #include <sys/socket.h>
      8 #include <netinet/in.h>
      9 #include <arpa/inet.h>
     10 #include <netdb.h>
     11 #include <errno.h>
     12 
     13 #define LINELEN 128
     14 extern int errno;
     15 
     16 int TCPecho(const char *host, const char *service);
     17 int errexit(const char *format,...);
     18 int connectsock(const char *host, const char *service, const char *transport );
     19 int connectTCP(const char *host, const char *service);
     20 
     21 int main(int argc, char *argv[]){
     22     char *host= "localhost";
     23     char *service= "echo";
     24     switch(argc){
     25 case 1:
     26     host = "localhost";
     27     break;
     28 case 3:
     29     service = argv[2];
     30 case 2:
     31     host=argv[1];
     32     break;
     33 default:
     34     fprintf(stderr,"usage:TCPecho[host[port]]
    ");
     35     exit(1);
     36     }
     37     TCPecho(host,service);
     38     exit(0);
     39 }
     40 int TCPecho(const char *host,const char *service){
     41     char buf[LINELEN+1];
     42     int s,n;
     43     int outchars, inchars;
     44     s=connectTCP(host, service);
     45     while(fgets(buf,sizeof(buf),stdin)){
     46         buf[LINELEN]='';
     47         outchars=strlen(buf);
     48         (void)write(s,buf,outchars);
     49         for(inchars=0;inchars<outchars;inchars+=n){
     50             n=read(s,&buf[inchars],outchars-inchars);
     51             if(n<0)
     52                     errexit("socker read failed: %s
    ",strerror(errno));
     53         }
     54         fputs(buf,stdout);
     55     }
     56 }
     57 int errexit(const char *format,...){
     58     va_list arg;
     59     va_start(arg, format);
     60     vfprintf(stderr,format,arg);
     61     va_end(arg);
     62     exit(1);
     63 }
     64 int connectsock(const char *host, const char *service, const char *transport )
     65 /*
     66  * Arguments:
     67  *      host      - name of host to which connection is desired
     68  *      service   - service associated with the desired port
     69  *      transport - name of transport protocol to use ("tcp" or "udp")
     70  */
     71 {
     72     struct hostent  *phe;   /* pointer to host information entry    */
     73     struct servent  *pse;   /* pointer to service information entry */
     74     struct protoent *ppe;   /* pointer to protocol information entry*/
     75     struct sockaddr_in sin; /* an Internet endpoint address     */
     76     int s, type;    /* socket descriptor and socket type    */
     77 
     78 
     79     memset(&sin, 0, sizeof(sin));
     80     sin.sin_family = AF_INET;
     81 
     82     /* Map service name to port number */
     83     if ( pse = getservbyname(service, transport) )
     84         sin.sin_port = pse->s_port;
     85     else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)
     86         errexit("can't get "%s" service entry
    ", service);
     87 
     88     /* Map host name to IP address, allowing for dotted decimal */
     89     if ( phe = gethostbyname(host) )
     90         memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
     91     else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
     92         errexit("can't get "%s" host entry
    ", host);
     93 
     94     /* Map transport protocol name to protocol number */
     95     if ( (ppe = getprotobyname(transport)) == 0)
     96         errexit("can't get "%s" protocol entry
    ", transport);
     97 
     98     /* Use protocol to choose a socket type */
     99     if (strcmp(transport, "udp") == 0)
    100         type = SOCK_DGRAM;
    101     else
    102         type = SOCK_STREAM;
    103 
    104     /* Allocate a socket */
    105     s = socket(PF_INET, type, ppe->p_proto);
    106     if (s < 0)
    107         errexit("can't create socket: %s
    ", strerror(errno));
    108 
    109     /* Connect the socket */
    110     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    111         errexit("can't connect to %s.%s: %s
    ", host, service,
    112             strerror(errno));
    113     return s;
    114 }
    115 int connectTCP(const char *host, const char *service){
    116     return connectsock(host,service,"tcp");
    117 }

    二、针对echo服务的并发的面向连接的服务器软件的实现

    1.网络拓扑结构:

    2.源码:

      1 #define _USE_BSD
      2 #include <stdio.h>
      3 #include <stdlib.h>
      4 #include <unistd.h>
      5 #include <string.h>
      6 #include <stdarg.h>
      7 #include <sys/types.h>
      8 #include <sys/socket.h>
      9 #include <netinet/in.h>
     10 #include <arpa/inet.h>
     11 #include <netdb.h>
     12 #include <signal.h>
     13 #include <errno.h>
     14 
     15 #define QLEN 32
     16 #define BUFSIZE 4096
     17 extern int errno;
     18 unsigned short portbase = 0;
     19 
     20 void reaper(int);
     21 int TCPechod(int fd);
     22 int errexit(const char *format,...);
     23 int passivesock(const char *service, const char *transport, int qlen);
     24 int passiveTCP(const char *service,int qlen);
     25 
     26 int main(int argc, char *argv[]){
     27     char *service= "echo";
     28     struct sockaddr_in fsin;
     29     unsigned int alen;
     30     int msock,ssock;
     31     switch(argc){
     32 case 1:
     33     break;
     34 case 2:
     35     service=argv[1];
     36     break;
     37 default:
     38     errexit("usage: TCPechod [port]
    ");
     39     }
     40 
     41     msock=passiveTCP(service,QLEN);
     42     (void)signal(SIGCHLD,(__sighandler_t)QLEN);
     43 
     44     while(1){
     45         alen=sizeof(fsin);
     46         ssock=accept(msock,(struct sockaddr *)&fsin,&alen);
     47         if(ssock<0){
     48             if(errno==EINTR)    continue;
     49             errexit("accept: %s
    ",strerror(errno));
     50         }
     51         switch(fork()){
     52     case 0:
     53         (void)close(msock);
     54         exit(TCPechod(ssock));
     55     default:
     56         (void)close(ssock);
     57         break;
     58     case -1:
     59         errexit("fork: %s
    ",strerror(errno));
     60         }
     61     }
     62 }
     63 
     64 void reaper(int sig){
     65     int status;
     66     while(wait3(&status,WNOHANG,(struct rusage *)0)>=0) ;
     67 }
     68 int TCPechod(int fd){
     69     char buf[BUFSIZ];
     70     int cc;
     71 
     72     while(cc=read(fd,buf,sizeof(buf))){
     73         if(cc<0)
     74             errexit("echo read: %s
    ",strerror(errno));
     75         if(write(fd,buf,cc)<0)
     76             errexit("echo write: %s
    ",strerror(errno));
     77     }
     78     return 0;
     79 }
     80 int errexit(const char *format,...){
     81     va_list arg;
     82     va_start(arg, format);
     83     vfprintf(stderr,format,arg);
     84     va_end(arg);
     85     exit(1);
     86 }
     87 int passivesock(const char *service, const char *transport, int qlen)
     88 /*
     89  * Arguments:
     90  *      service   - service associated with the desired port
     91  *      transport - transport protocol to use ("tcp" or "udp")
     92  *      qlen      - maximum server request queue length
     93  */
     94 {
     95 
     96     struct servent*pse;/* pointer to service information entry*/
     97     struct protoent *ppe;/* pointer to protocol information entry*/
     98     struct sockaddr_in sin;/* an Internet endpoint address*/
     99     int s, type;/* socket descriptor and socket type*/
    100 
    101     memset(&sin, 0, sizeof(sin));
    102     sin.sin_family = AF_INET;
    103     sin.sin_addr.s_addr = INADDR_ANY;
    104 
    105         /* Map service name to port number */
    106     if ( pse = getservbyname(service, transport) )
    107     sin.sin_port = htons(ntohs((unsigned short)pse->s_port)+ portbase);
    108     else
    109               if ((sin.sin_port=htons((unsigned short)atoi(service)+portbase)) == 0)
    110     errexit("can't create passive service %d 
    ",sin.sin_port);
    111 
    112         /* Map protocol name to protocol number */
    113     if ( (ppe = getprotobyname(transport)) == 0)
    114     errexit("can't get "%s" protocol entry
    ", transport);
    115 
    116         /* Use protocol to choose a socket type */
    117     if (strcmp(transport, "udp") == 0)
    118     type = SOCK_DGRAM;
    119     else
    120     type = SOCK_STREAM;
    121 
    122         /* Allocate a socket */
    123     s = socket(PF_INET, type, ppe->p_proto);
    124     if (s < 0)
    125     errexit("can't create socket: %s
    ", strerror(errno));
    126 
    127         /* Bind the socket */
    128     if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    129     errexit("can't bind to %s port: %s
    ", service,
    130     strerror(errno));
    131     if (type == SOCK_STREAM && listen(s, qlen) < 0)
    132     errexit("can't listen on %s port: %s
    ", service,
    133     strerror(errno));
    134     return s;
    135 }
    136 int passiveTCP(const char *service,int qlen){
    137     return passivesock(service,"tcp",qlen);
    138 }

    三、针对TIME服务的UDP客户软件的实现

    1.网络拓扑结构:

    2.源码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <unistd.h>
      4 #include <string.h>
      5 #include <stdarg.h>
      6 #include <sys/types.h>
      7 #include <sys/socket.h>
      8 #include <netinet/in.h>
      9 #include <arpa/inet.h>
     10 #include <netdb.h>
     11 #include <time.h>
     12 #include <errno.h>
     13 
     14 #define BUFSIZE 64
     15 #define UNIXEPOCH 2208988800UL
     16 #define MSG "what time is it?
    "
     17 extern int errno;
     18 
     19 int errexit(const char *format,...);
     20 int connectsock(const char *host, const char *service, const char *transport );
     21 int connectUDP(const char *host, const char *service);
     22 
     23 int main(int argc, char *argv[]){
     24     char *host= "localhost";
     25     char *service= "time";
     26     time_t now;
     27     int s,n;
     28 
     29     switch(argc){
     30 case 1:
     31     host = "localhost";
     32     break;
     33 case 3:
     34     service = argv[2];
     35 case 2:
     36     host=argv[1];
     37     break;
     38 default:
     39     fprintf(stderr,"usage: UDPtime[host[port]]
    ");
     40     exit(1);
     41     }
     42 
     43     s=connectUDP(host,service);
     44     (void)write(s,MSG,strlen(MSG));
     45 
     46     n=read(s,(char *)&now,sizeof(now));
     47     if(n<0)     errexit("read failed: %s
    ",strerror(errno));
     48     now=ntohl((unsigned long)now);
     49     now-=UNIXEPOCH;
     50     printf("%s",ctime(&now));
     51     exit(0);
     52 }
     53 int errexit(const char *format,...){
     54     va_list arg;
     55     va_start(arg, format);
     56     vfprintf(stderr,format,arg);
     57     va_end(arg);
     58     exit(1);
     59 }
     60 int connectsock(const char *host, const char *service, const char *transport )
     61 /*
     62  * Arguments:
     63  *      host      - name of host to which connection is desired
     64  *      service   - service associated with the desired port
     65  *      transport - name of transport protocol to use ("tcp" or "udp")
     66  */
     67 {
     68     struct hostent  *phe;   /* pointer to host information entry    */
     69     struct servent  *pse;   /* pointer to service information entry */
     70     struct protoent *ppe;   /* pointer to protocol information entry*/
     71     struct sockaddr_in sin; /* an Internet endpoint address     */
     72     int s, type;    /* socket descriptor and socket type    */
     73 
     74 
     75     memset(&sin, 0, sizeof(sin));
     76     sin.sin_family = AF_INET;
     77 
     78     /* Map service name to port number */
     79     if ( pse = getservbyname(service, transport) )
     80         sin.sin_port = pse->s_port;
     81     else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)
     82         errexit("can't get "%s" service entry
    ", service);
     83 
     84     /* Map host name to IP address, allowing for dotted decimal */
     85     if ( phe = gethostbyname(host) )
     86         memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
     87     else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
     88         errexit("can't get "%s" host entry
    ", host);
     89 
     90     /* Map transport protocol name to protocol number */
     91     if ( (ppe = getprotobyname(transport)) == 0)
     92         errexit("can't get "%s" protocol entry
    ", transport);
     93 
     94     /* Use protocol to choose a socket type */
     95     if (strcmp(transport, "udp") == 0)
     96         type = SOCK_DGRAM;
     97     else
     98         type = SOCK_STREAM;
     99 
    100     /* Allocate a socket */
    101     s = socket(PF_INET, type, ppe->p_proto);
    102     if (s < 0)
    103         errexit("can't create socket: %s
    ", strerror(errno));
    104 
    105     /* Connect the socket */
    106     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    107         errexit("can't connect to %s.%s: %s
    ", host, service,
    108             strerror(errno));
    109     return s;
    110 }
    111 int connectUDP(const char *host, const char *service){
    112     return connectsock(host,service,"udp");
    113 }

    四、针对TIME服务的UDP服务器端软件的实现

    1.网络拓扑结构:

    2.源码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <unistd.h>
      4 #include <string.h>
      5 #include <stdarg.h>
      6 #include <sys/types.h>
      7 #include <sys/socket.h>
      8 #include <netinet/in.h>
      9 #include <arpa/inet.h>
     10 #include <netdb.h>
     11 #include <errno.h>
     12 
     13 #define UNIXEPOCH 2208988800UL
     14 
     15 extern int errno;
     16 unsigned short portbase = 0;
     17 
     18 int errexit(const char *format,...);
     19 int passivesock(const char *service, const char *transport, int qlen);
     20 int passiveUDP(const char *service);
     21 
     22 int main(int argc, char *argv[]){
     23     char *service= "time";
     24     struct sockaddr_in fsin;
     25     char buf[1];
     26     int sock;
     27     time_t now;
     28     unsigned int alen;
     29 
     30     switch(argc){
     31 case 1:
     32     break;
     33 case 2:
     34     service=argv[1];
     35     break;
     36 default:
     37     errexit("usage: UDPtimed [port]
    ");
     38     }
     39 
     40     sock=passiveUDP(service);
     41 
     42     while(1){
     43         alen=sizeof(fsin);
     44         if(recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr *)&fsin,&alen)<0)
     45             errexit("recvfrom: %s
    ",strerror(errno));
     46         (void)time(&now);
     47         now=htonl((unsigned long)(now+UNIXEPOCH));
     48         (void)sendto(sock,(char*)&now,sizeof(now),0,(struct sockaddr *)&fsin,sizeof(fsin));
     49     }
     50 }
     51 
     52 int errexit(const char *format,...){
     53     va_list arg;
     54     va_start(arg, format);
     55     vfprintf(stderr,format,arg);
     56     va_end(arg);
     57     exit(1);
     58 }
     59 int passivesock(const char *service, const char *transport, int qlen)
     60 /*
     61  * Arguments:
     62  *      service   - service associated with the desired port
     63  *      transport - transport protocol to use ("tcp" or "udp")
     64  *      qlen      - maximum server request queue length
     65  */
     66 {
     67 
     68     struct servent*pse;/* pointer to service information entry*/
     69     struct protoent *ppe;/* pointer to protocol information entry*/
     70     struct sockaddr_in sin;/* an Internet endpoint address*/
     71     int s, type;/* socket descriptor and socket type*/
     72 
     73     memset(&sin, 0, sizeof(sin));
     74     sin.sin_family = AF_INET;
     75     sin.sin_addr.s_addr = INADDR_ANY;
     76 
     77         /* Map service name to port number */
     78     if ( pse = getservbyname(service, transport) )
     79     sin.sin_port = htons(ntohs((unsigned short)pse->s_port)+ portbase);
     80     else
     81               if ((sin.sin_port=htons((unsigned short)atoi(service)+portbase)) == 0)
     82     errexit("can't create passive service %d 
    ",sin.sin_port);
     83 
     84         /* Map protocol name to protocol number */
     85     if ( (ppe = getprotobyname(transport)) == 0)
     86     errexit("can't get "%s" protocol entry
    ", transport);
     87 
     88         /* Use protocol to choose a socket type */
     89     if (strcmp(transport, "udp") == 0)
     90     type = SOCK_DGRAM;
     91     else
     92     type = SOCK_STREAM;
     93 
     94         /* Allocate a socket */
     95     s = socket(PF_INET, type, ppe->p_proto);
     96     if (s < 0)
     97     errexit("can't create socket: %s
    ", strerror(errno));
     98 
     99         /* Bind the socket */
    100     if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    101     errexit("can't bind to %s port: %s
    ", service,
    102     strerror(errno));
    103     if (type == SOCK_STREAM && listen(s, qlen) < 0)
    104     errexit("can't listen on %s port: %s
    ", service,
    105     strerror(errno));
    106     return s;
    107 }
    108 int passiveUDP(const char *service){
    109     return passivesock(service,"udp",0);
    110 }

    这里是用的我实验时的代码,前两个是关于echo服务的客户端与服务器端,有下面运行截图:

    后两个是关于time服务的,有下面运行截图:

    实验时由于多次运行验证,总会出现端口占用的情况,于是这里每次运行时都输入程序的入口参数(就是main函数里的形参),自选端口,方便至极。还有就是代码里多个函数可以写入多个cpp里,这里偷懒了。

  • 相关阅读:
    BZOJ3562 : [SHOI2014]神奇化合物
    BZOJ3559 : [Ctsc2014]图的分割
    BZOJ3551 : [ONTAK2010]Peaks加强版
    BZOJ3542:DZY Loves March
    李洪强iOS开发之
    iOS学习之iOS沙盒(sandbox)机制和文件操作1
    iOS学习之iOS沙盒(sandbox)机制和文件操作
    stringByAppendingPathComponent和stringByAppendingString 的区别
    iOS开发:Toast for iPhone
    深度解析开发项目之 01
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4553542.html
Copyright © 2011-2022 走看看