d4ba728fcb0ab2d65109ef41db4690a68be54b00
[gapil.git] / sources / SimpleEchoTCPServer.c
1 /* SimpleEchoTCPServer.c
2  * 
3  * Copyright (C) 2001 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /****************************************************************
20  *
21  * Program echod: 
22  * Elementary TCP server for echo service (port 7)
23  *
24  * Author: Simone Piccardi
25  * Jun. 2001
26  *
27  * Usage: echod
28  *
29  * $Id: SimpleEchoTCPServer.c,v 1.5 2002/12/03 11:06:05 piccardi Exp $ 
30  *
31  ****************************************************************/
32 /* 
33  * Include needed headers
34  */
35 #include <sys/types.h>   /* predefined types */
36 #include <unistd.h>      /* include unix standard library */
37 #include <arpa/inet.h>   /* IP addresses conversion utiliites */
38 #include <sys/socket.h>  /* socket library */
39 #include <stdio.h>       /* include standard I/O library */
40 #include <time.h>
41
42 #define BACKLOG 10
43 #define MAXLINE 256
44
45 /* Subroutines declaration */
46 void usage(void);
47 void SockEcho(int sockfd);
48 /* Program beginning */
49 int main(int argc, char *argv[])
50 {
51 /* 
52  * Variables definition  
53  */
54     int list_fd, conn_fd;
55     pid_t pid;
56     struct sockaddr_in serv_add;
57     /*
58      * Input section: decode parameters passed in the calling 
59      * Use getopt function
60      */
61     int i;
62     opterr = 0;  /* don't want writing to stderr */
63     while ( (i = getopt(argc, argv, "h")) != -1) {
64         switch (i) {
65         /* 
66          * Handling options 
67          */ 
68         case 'h':  
69             printf("Wrong -h option use\n");
70             usage();
71             return(0);
72             break;
73         case '?':   /* unrecognized options */
74             printf("Unrecognized options -%c\n",optopt);
75             usage();
76         default:    /* should not reached */
77             usage();
78         }
79     }
80     /* ***********************************************************
81      * 
82      *           Options processing completed
83      *
84      *                Main code beginning
85      * 
86      * ***********************************************************/
87     /* create socket */
88     if ( (list_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
89         perror("Socket creation error");
90         exit(-1);
91     }
92     /* initialize address */
93     memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
94     serv_add.sin_family = AF_INET;                  /* address type is INET */
95     serv_add.sin_port = htons(7);                   /* echo port is 7 */
96     serv_add.sin_addr.s_addr = htonl(INADDR_ANY);   /* connect from anywhere */
97     /* bind socket */
98     if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
99         perror("bind error");
100         exit(-1);
101     }
102     /* listen on socket */
103     if (listen(list_fd, BACKLOG) < 0 ) {
104         perror("listen error");
105         exit(-1);
106     }
107     /* handle echo to client */
108     while (1) {
109         /* accept connection */
110         if ( (conn_fd = accept(list_fd, NULL, NULL)) < 0) {
111             perror("accept error");
112             exit(-1);
113         }
114         /* fork to handle connection */
115         if ( (pid = fork()) < 0 ){
116             perror("fork error");
117             exit(-1);
118         }
119         if (pid == 0) {      /* child */
120             close(list_fd);          /* close listening socket */   
121             SockEcho(conn_fd);       /* handle echo */
122             exit(0);
123         } else {             /* parent */
124             close(conn_fd);          /* close connected socket */
125         }
126     }
127     /* normal exit, never reached */
128     exit(0);
129 }
130 /*
131  * routine to print usage info and exit
132  */
133 void usage(void) {
134     printf("Simple daytime server\n");
135     printf("Usage:\n");
136     printf("  daytimed [-h] \n");
137     printf("  -h           print this help\n");
138     exit(1);
139 }
140 /*
141  * routine to handle echo for connection
142  */
143 void SockEcho(int sockfd) {
144     char buffer[MAXLINE];
145     int nread, nwrite;
146     
147     /* main loop, reading 0 char means client close connection */
148     while ( (nread = read(sockfd, buffer, MAXLINE)) != 0) {
149         printf("Letti %d bytes, %s ", nread, buffer);
150         nwrite = SockWrite(sockfd, buffer, nread);
151     }
152     return;
153 }