root/trunk/ciupdserx.c

Revision 389, 10.6 kB (checked in by heitor.barbieri, 3 weeks ago)

essage first commit

Line 
1/*
2..Server program that makes a connection for a byte stream socket in the Internet namespace.
3..Once it has connected to the server, it sends a text string to the server and gets the response.
4Returns 0 or a negative error value.
5*/
6/*
716.9.7 Byte Stream Connection Server Example
8The server end is much more complicated. Since we want to allow multiple clients to be connected to the server at the same time, it would be incorrect to wait for input from a single client by simply calling read or recv. Instead, the right thing to do is to use select (see Waiting for I/O) to wait for input on all of the open sockets. This also allows the server to deal with additional connection requests.
9This particular server doesn't do anything interesting once it has gotten a message from a client. It does close the socket for that client when it detects an end-of-file condition (resulting from the client shutting down its end of the connection).
10This program uses make_socket to set up the socket address; see Inet Example.
11*/
12
13#ifndef CISIS_H
14#define GEN_MAIN 1
15#endif
16
17#if GEN_MAIN
18     #include <stdio.h>
19     #include <errno.h>
20     #include <stdlib.h>
21     #include <unistd.h>
22     #include <sys/types.h>
23#endif /*  GEN_MAIN */
24
25     #include <sys/socket.h>
26     #include <netinet/in.h>
27     #include <netdb.h>
28     #include <time.h>
29
30#if GEN_MAIN
31     #define PORT          1417
32     #define BUFFERSIZE   51200
33#endif /*  GEN_MAIN */
34
35     #define REPLYSIZE    51200
36
37
38     int mainserver_make_socket (int cmd, uint16_t port);
39     int mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize);
40     int mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize);
41     int mainserver (int cmd, uint16_t port, char *buffer, int buffersize, int maxconnqueued);
42
43
44
45/*
46*/
47     int
48     mainserver_make_socket (int cmd, uint16_t port)
49     {
50       int sock;
51       struct sockaddr_in name;
52
53       /* Create the socket. */
54       sock = socket (PF_INET, SOCK_STREAM, 0);
55       if (sock < 0)
56         {
57           /*perror ("socket"); exit (EXIT_FAILURE);*/
58           return -1;
59         }
60
61       /* Give the socket a name. */
62       name.sin_family = AF_INET;
63       name.sin_port = htons (port);
64       name.sin_addr.s_addr = htonl (INADDR_ANY);
65       if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
66         {
67           /*perror ("bind"); exit (EXIT_FAILURE);*/
68           return -2;
69         }
70
71       return sock;
72     }
73
74
75     int
76     mainserver_write_to_client (int cmd, uint16_t port, int filedes, char *message, int messagesize)
77     {
78       int nbytes;
79                              /* yyyymmdd hh:mm:ss WDAY YDAY */
80       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
81       time_t secs_now;
82       struct tm *tp;
83       time(&secs_now); tp=localtime(&secs_now);
84       sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
85
86       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes): '%s' \n", port, filedes, timestamp, messagesize, message);
87       if (cmd == 2) fprintf (stderr, "Server [%d] [%d] [%s]: reply message (%d bytes) \n", port, filedes, timestamp, messagesize);
88
89       nbytes = write (filedes, message, messagesize);
90       if (nbytes < messagesize)
91         {
92           /* Write error */
93           /*perror ("write");*/
94           return -1;
95         }
96       else
97         return nbytes;
98     }
99
100
101     int
102     mainserver_read_from_client (int cmd, uint16_t port, int filedes, char *buffer, int buffersize)
103     {
104       int nbytes;
105
106       buffer[0]='\0';
107       nbytes = read (filedes, buffer, buffersize-1);
108       if (nbytes < 0)
109         {
110           /* Read error. */
111           /*perror ("read"); exit (EXIT_FAILURE);*/
112           return -2;
113         }
114       else
115         {
116#if TRACER
117           char *p=buffer;
118           int loop=nbytes;
119           fprintf (stderr, "read(%d): ",nbytes);
120           for (; loop--; p++) fprintf (stderr, "%c=%02x ",*p,(int)*p);
121           fprintf (stderr, "\n");
122#endif
123           /* EOF (nbytes=0) or Data read. */
124           buffer[nbytes]='\0';
125           return nbytes;
126         }
127     }
128
129
130/*
131     mainserver
132*/
133     int
134     mainserver (int cmd, uint16_t port, char *buffer, int buffersize, int maxconnqueued)
135     {
136       int sock;
137       fd_set active_fd_set, read_fd_set;
138       int i;
139       struct sockaddr_in clientname;
140       size_t size;
141       int shutdown=0; /* run */
142                              /* yyyymmdd hh:mm:ss WDAY YDAY */
143       char timestamp[80];    /* 123456789012345678901234 7  8 901 */
144       time_t secs_in;
145       time_t secs_now;
146       struct tm *tp;
147
148       /* Create the socket and set it up to accept connections. */
149       sock = mainserver_make_socket (cmd, port);
150
151       time(&secs_now); tp=localtime(&secs_now); secs_in=secs_now;
152       sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
153
154       if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got socket \n", port, sock, timestamp);
155
156       if (listen (sock, maxconnqueued) < 0)   /* <== at most 1 connection queued */
157         {
158           /*perror ("listen"); exit (EXIT_FAILURE);*/
159           return -1;
160         }
161
162       /* Initialize the set of active sockets. */
163       FD_ZERO (&active_fd_set);
164       FD_SET (sock, &active_fd_set);
165
166       while (!shutdown)
167         {
168           /* Block until input arrives on one or more active sockets. */
169           read_fd_set = active_fd_set;
170           if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
171             {
172               /*perror ("select"); exit (EXIT_FAILURE);*/
173               return -2;
174             }
175           /* Service all the sockets with input pending. */
176           for (i = 0; i < FD_SETSIZE; ++i) {
177             if (FD_ISSET (i, &read_fd_set))
178               {
179                 if (i == sock)
180                   {
181                     /* Connection request on original socket. */
182                     int new;
183                     size = sizeof (clientname);
184                     new = accept (sock,
185                                   (struct sockaddr *) &clientname,
186                                   &size);
187                     if (new < 0)
188                       {
189                         /*perror ("accept"); exit (EXIT_FAILURE);*/
190                         return -3;
191                       }
192                     if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: connect from host %s, port %hd \n", port, sock, timestamp, inet_ntoa (clientname.sin_addr), ntohs (clientname.sin_port));
193                     FD_SET (new, &active_fd_set);
194                   }
195                 else
196                   {
197                     /* Data arriving on an already-connected socket. */
198                     int nread = mainserver_read_from_client (cmd, port, i, buffer, buffersize);
199                     int code;
200                     char replybuf[REPLYSIZE];
201                     char *reply=replybuf;
202                     replybuf[0]='\0';
203
204                     time(&secs_now); tp=localtime(&secs_now);
205                     sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
206
207                     if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: got message (%d bytes): '%s' \n", port, sock, timestamp, nread, buffer);
208
209                     if (strlen(buffer) == 0)              {         reply="server4 100 eof msg\n"; /* never */          code=100; }
210                     else
211                     if (strcmp(buffer,"\n") == 0)         {         reply="server4 101 null msg\n";                     code=101; }
212                     else
213                     if (strcmp(buffer+nread-1,"\n") != 0) {         reply="server4 505 bad msg\n";                      code=500; }
214                     else
215                     if (strcmp(buffer,"shutdown\n") == 0) {         reply="server4 200 thanks\n";                       code=0;   shutdown=1; }
216                     else
217                     if (strcmp(buffer,"hello\n") == 0)    {         reply="server4 200 hi\n";                           code=200; }
218                     else
219                     if (strncmp(buffer,"echo ",5) == 0)   { sprintf(reply,"server4 200 %s\n",buffer+5); reply=replybuf; code=200; }
220                     else
221                                                           {         reply="server4 404 invalid msg\n";                  code=400; }
222
223                     /* Response */
224                     if (strlen(reply) > 0) {
225                       int nbytes=strlen(reply);
226                       nbytes = mainserver_write_to_client (cmd, port, i, reply, nbytes);
227                       if (nbytes < 0)
228                         {
229                           /*perror ("write (client)");*/
230                           close (i);
231                           FD_CLR (i, &active_fd_set);
232                           /* return -4; */
233                         }
234                     }
235
236                     close (i);
237                     FD_CLR (i, &active_fd_set);
238
239                   } /* end data read */
240
241               } /* end if FD_ISSET */
242
243               if (shutdown) break;
244
245           } /* end for FD_SETSIZE */
246         } /* end while */
247
248         /* Release the socket. */
249         close (sock);
250
251         time(&secs_now); tp=localtime(&secs_now);
252         sprintf(timestamp,"%04d%02d%02d %02d%02d%02d %1d %3d", 1900+tp->tm_year,tp->tm_mon+1,tp->tm_mday, tp->tm_hour,tp->tm_min,tp->tm_sec, tp->tm_wday,tp->tm_yday);
253
254         if (cmd == 3) fprintf (stderr, "Server [%d] [%d] [%s]: close socket (%"_LD_" seconds) \n", port, sock, timestamp,(LONGX)secs_now-secs_in);
255
256         return 0;
257
258     } /* end of mainserver */
259
260
261
262
263/* Main
264
265./server4 3
266./server4 3 2>>xlog &
267
268*/
269
270#if GEN_MAIN
271     int
272     main(int argc, char *argv[])
273     {
274       /* calling parameters */
275       int cmd;
276       uint16_t port=PORT;
277       int rc;
278
279       char buffer[BUFFERSIZE];
280
281       if (argc == 1) {
282          fprintf(stderr, "server4 0=plain|1=xml|2=tell|3=trace [port%d] \n",PORT);
283         exit (EXIT_FAILURE);
284       }
285
286       cmd=atoi(argv[1]);
287
288       if (argc > 2) port=(uint16_t)atoi(argv[2]);
289
290       if (cmd >= 3) fprintf(stderr, "server4: %d \n",port);
291
292       rc = mainserver(cmd, port, buffer, BUFFERSIZE, 1);
293
294       if (rc < 0) {
295         if (cmd >= 3) fprintf(stderr, "server4: exit_failure %d \n", rc);
296         exit (EXIT_FAILURE);
297       }
298
299       if (cmd >= 3) fprintf(stderr, "server4: exit_success \n");
300       exit (EXIT_SUCCESS);
301     }
302#endif /*  GEN_MAIN */
303
304#undef GEN_MAIN
305
Note: See TracBrowser for help on using the browser.