35a2737cc061cecaa644c1a7dc539e2e07156943
[gapil.git] / sources / SimpleEchoTCPServer.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: SimpleEchoTCPServer.c,v 1.1 2001/06/10 11:47:17 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 /* Subroutine declaration */
30 void usage(void);
31 void SockEcho(int sockfd);
32
33 /* Program begining */
34 int main(int argc, char *argv[])
35 {
36 /* 
37  * Variables definition  
38  */
39     int list_fd, conn_fd;
40     pid_t pid;
41     struct sockaddr_in serv_add;
42     /*
43      * Input section: decode parameters passed in the calling 
44      * Use getopt function
45      */
46     int i;
47     opterr = 0;  /* don't want writing to stderr */
48     while ( (i = getopt(argc, argv, "h")) != -1) {
49         switch (i) {
50         /* 
51          * Handling options 
52          */ 
53         case 'h':  
54             printf("Wrong -h option use\n");
55             usage();
56             return(0);
57             break;
58         case '?':   /* unrecognized options */
59             printf("Unrecognized options -%c\n",optopt);
60             usage();
61         default:    /* should not reached */
62             usage();
63         }
64     }
65     /* ***********************************************************
66      * 
67      *           Options processing completed
68      *
69      *                Main code beginning
70      * 
71      * ***********************************************************/
72     /* create socket */
73     if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
74         perror("Socket creation error");
75         exit(-1);
76     }
77     /* initialize address */
78     memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
79     serv_add.sin_family = AF_INET;                  /* address type is INET */
80     serv_add.sin_port = htons(13);                  /* daytime port is 13 */
81     serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
82     /* bind socket */
83     if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
84         perror("bind error");
85         exit(-1);
86     }
87     /* listen on socket */
88     if (listen(list_fd, BACKLOG) < 0 ) {
89         perror("listen error");
90         exit(-1);
91     }
92     /* handle echo to client */
93     while (1) {
94         /* accept connection */
95         if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
96             perror("accept error");
97             exit(-1);
98         }
99         /* fork to handle connection */
100         if ( (pid = fork()) < 0 ){
101             perror("fork error");
102             exit(-1);
103         }
104         if (pid == 0) {      /* child */
105             close(list_fd);          /* close listening socket */   
106             SockEcho(conn_fd);       /* handle echo */
107             exit(0);
108         } else {             /* parent */
109             close(conn_fd);          /* close connected socket */
110         }
111     }
112     /* normal exit, never reached */
113     exit(0);
114 }
115 /*
116  * routine to print usage info and exit
117  */
118 void usage(void) {
119     printf("Simple daytime server\n");
120     printf("Usage:\n");
121     printf("  daytimed [-h] \n");
122     printf("  -h           print this help\n");
123     exit(1);
124 }
125 /*
126  * routine to handle echo for connection
127  */
128 void SockEcho(int sockfd) {
129     char buffer[MAXLINE];
130     int nread, nwrite;
131     
132     /* main loop, reading 0 char means client close connection */
133     while ( (nread = SockRead(sockfd, buffer, MAXLINE)) != 0) {
134         nwrite = SockWrite(sockfd, buffer, nread);
135     }
136     return;
137 }