Ho detto solo $Date$, non anche $Id$
[gapil.git] / sources / ElemEchoTCPServer.c
1 /****************************************************************
2  *
3  * Program echo_tcp_server.c: 
4  * Elementary TCP server for echo service (port 7)
5  *
6  * Author: Simone Piccardi
7  * Jun. 2001
8  *
9  * Usage: echod
10  *
11  * $Id: ElemEchoTCPServer.c,v 1.2 2001/06/20 22:03:37 piccardi Exp $ 
12  *
13  ****************************************************************/
14 /* 
15  * Include needed headers
16  */
17 #include <sys/types.h>   /* predefined types */
18 #include <unistd.h>      /* include unix standard library */
19 #include <arpa/inet.h>   /* IP addresses conversion utiliites */
20 #include <sys/socket.h>  /* socket library */
21 #include <stdio.h>       /* include standard I/O library */
22 #include <time.h>
23
24 #include "wrappers.h"
25
26 #define BACKLOG 10
27 #define MAXLINE 256
28
29 /* Subroutines declaration */
30 void usage(void);
31 void ServEcho(int sockfd);
32 /* Program beginning */
33 int main(int argc, char *argv[])
34 {
35 /* 
36  * Variables definition  
37  */
38     int list_fd, conn_fd;
39     pid_t pid;
40     struct sockaddr_in serv_add;
41     /*
42      * Input section: decode parameters passed in the calling 
43      * Use getopt function
44      */
45     int i;
46     opterr = 0;  /* don't want writing to stderr */
47     while ( (i = getopt(argc, argv, "h")) != -1) {
48         switch (i) {
49         /* 
50          * Handling options 
51          */ 
52         case 'h':  
53             printf("Wrong -h option use\n");
54             usage();
55             return(0);
56             break;
57         case '?':   /* unrecognized options */
58             printf("Unrecognized options -%c\n",optopt);
59             usage();
60         default:    /* should not reached */
61             usage();
62         }
63     }
64     /* ***********************************************************
65      * 
66      *           Options processing completed
67      *
68      *                Main code beginning
69      * 
70      * ***********************************************************/
71     /* create socket */
72     if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
73         perror("Socket creation error");
74         exit(-1);
75     }
76     /* initialize address */
77     memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
78     serv_add.sin_family = AF_INET;                  /* address type is INET */
79     serv_add.sin_port = htons(7);                   /* echo port is 7 */
80     serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
81     /* bind socket */
82     if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
83         perror("bind error");
84         exit(-1);
85     }
86     /* listen on socket */
87     if (listen(list_fd, BACKLOG) < 0 ) {
88         perror("listen error");
89         exit(-1);
90     }
91     /* handle echo to client */
92     while (1) {
93         /* accept connection */
94         if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
95             perror("accept error");
96             exit(-1);
97         }
98         /* fork to handle connection */
99         if ( (pid = fork()) < 0 ){
100             perror("fork error");
101             exit(-1);
102         }
103         if (pid == 0) {      /* child */
104             close(list_fd);          /* close listening socket */   
105             SockEcho(conn_fd);       /* handle echo */
106             exit(0);
107         } else {             /* parent */
108             close(conn_fd);          /* close connected socket */
109         }
110     }
111     /* normal exit, never reached */
112     exit(0);
113 }
114 /*
115  * routine to print usage info and exit
116  */
117 void usage(void) {
118     printf("Simple daytime server\n");
119     printf("Usage:\n");
120     printf("  daytimed [-h] \n");
121     printf("  -h           print this help\n");
122     exit(1);
123 }
124 /*
125  * routine to handle echo for connection
126  */
127 void ServEcho(int sockfd) {
128     char buffer[MAXLINE];
129     int nread, nwrite;
130     
131     /* main loop, reading 0 char means client close connection */
132     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
133         printf("Letti %d bytes, %s ", nread, buffer);
134         nwrite = SockWrite(sockfd, buffer, nread);
135     }
136     return;
137 }