source: SH_SHM/trunk/source/port_io.c @ 374

Revision 78, 9.5 KB checked in by marcus, 15 years ago (diff)

r61 | walther | 2008-11-10 16:11:15 +0100 (Mo, 10 Nov 2008) | 3 lines

  • 64bit compatibility for net I/O
  • sample configuration file for shd process
Line 
1/* file port_io.c
2 *      =========
3 *
4 * version 3, 9-Jul-2006
5 *
6 * socket server test program
7 *
8 * K. Stammler, 28-Jun-2006
9 * M. Walther, 22-Oct-2008
10 */
11
12
13#include <arpa/inet.h>
14#include <stdio.h>
15#include <string.h>
16#include <errno.h>
17#include <stdlib.h>
18#include <unistd.h>
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <netinet/in.h>
22#include <netdb.h>
23#include "port_io.h"
24
25
26#define cPio_MAXBUF  512
27
28/* local prototypes */
29int pio_make_socket( uint16_t port );
30
31
32/* global variables */
33static int     piov_main_socket;     /* main socket for new connections */
34static fd_set  piov_active_fd_set;   /* active file descriptor set */
35static fd_set  piov_read_fd_set;     /* current file descriptor set */
36static FILE    *piov_log=NULL;       /* file pointer for log messages */
37
38
39/*----------------------------------------------------------------------------*/
40
41
42
43void pio_init_main_socket( int portno )
44
45/* initialises main socket for connections
46 *
47 * parameters of routine
48 * int        portno; input; IP port number
49 */
50{
51        /* local variables */
52
53        /* executable code */
54
55        /* Create the socket and set it up to accept connections. */
56        piov_main_socket = pio_make_socket( portno );
57        if  (listen(piov_main_socket,1) < 0)  {
58                perror( "error on listen command" );
59                exit( EXIT_FAILURE );
60        } /*endif*/
61
62        /*printf( "--> socket %d initialised\n", piov_main_socket );*/
63
64        /* Initialize the set of active sockets. */
65        FD_ZERO( &piov_active_fd_set );
66        FD_SET( piov_main_socket, &piov_active_fd_set );
67
68} /* end of pio_init_main_socket */
69
70
71
72/*----------------------------------------------------------------------------*/
73
74
75
76void pio_read( int maxbuf, char buffer[], int *buflth, int *tmpsock )
77
78/* Read data from port opened with pio_init_main_socket
79 *
80 * parameters of routine
81 * int        maxbuf;      input; maximum length of buffer
82 * char       buffer[];    output; data read from socket
83 * int        *buflth;     output; number of bytes in the buffer
84 * int        *tmpsock;    output; socket from which data was read or -1
85 *                                 this argument may be NULL
86 */
87{
88        /* local variables */
89        int      i;                          /* counter */
90        struct sockaddr_in clientname;       /* name of client */
91        socklen_t   size;                       /* size of clientname structure */
92
93        /* executable code */
94
95        *buffer = '\0';
96        *buflth = 0;
97
98        /* Block until input arrives on one or more active sockets. */
99        piov_read_fd_set = piov_active_fd_set;
100        if  (select(FD_SETSIZE, &piov_read_fd_set, NULL, NULL, NULL) < 0)  {
101                perror("error on select comand");
102                exit( EXIT_FAILURE );
103        } /*endif*/
104
105        /* Service all the sockets with input pending. */
106        for (i=0; i<FD_SETSIZE; ++i)
107                if (FD_ISSET(i,&piov_read_fd_set))  {
108                        if  (i == piov_main_socket)  {
109                                /* Connection request on original socket. */
110                                int new;  /* new socket ID */
111                                size = sizeof( clientname );
112                                new = accept(piov_main_socket, (struct sockaddr *) &clientname,
113                                        &size );
114                                if  (new < 0)  {
115                                        perror( "error on accept command" );
116                                        exit( EXIT_FAILURE );
117                                } /*endif*/
118                                if  (piov_log != NULL)
119                                        fprintf (piov_log, "port_io-Server: connect from host %s, port %hd.\n",
120                                                inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port) );
121                                FD_SET( new, &piov_active_fd_set );
122                                /*printf( "--> new active socket %d\n", new );*/
123                        } else {
124                                /* Data arriving on an already-connected socket. */
125                                pio_read_from_client( i, maxbuf, buffer, buflth );
126                                /*printf( "--> reading from socket %d, got %d bytes\n", i, *buflth );*/
127                                if  (*buflth > 0)  {
128                                        if  (*buffer < ' ')  {
129                                                /* ignore lines starting with control chars */
130                                                *buffer = '\0';
131                                                *buflth = 0;
132                                        } /*endif*/
133                                        /*printf( "--> returning from pio_read\n" );*/
134                                        if  (tmpsock != NULL)  *tmpsock = i;
135                                        return;
136                                } else {
137                                        /* no more data, socket should be closed */
138                                        close( i );
139                                        FD_CLR( i, &piov_active_fd_set );
140                                        *buffer = '\0';
141                                        /*printf( "--> close socket %d\n", i );*/
142                                        if  (tmpsock != NULL)  *tmpsock = -1;
143                                } /*endif*/
144                        } /*endif*/
145                } /*endif*/
146
147} /* end of pio_read */
148
149
150
151/*----------------------------------------------------------------------------*/
152
153
154
155void pio_read_from_client( int fd, int maxbuf, char buffer[], int *nbytes )
156
157/* Read message from client
158 *
159 * parameters of routine
160 * int        fd;       input; socket ID
161 * int        maxbuf;   input; maximum buffer length
162 * char       buffer[]; output; message read from socket
163 * int        *nbytes;  output; number of bytes read
164 */
165{
166        /* local variables */
167
168        /* executable code */
169
170        *nbytes = read( fd, buffer, maxbuf );
171
172        if  (*nbytes < 0)  {
173                /* Read error. */
174                perror( "read error of server" );
175                *buffer = '\0';
176                *nbytes = 0;
177        } else if  (*nbytes == 0)  {
178                *buffer = '\0';
179        } /*endif*/
180
181} /* end of pio_read_from_client */
182
183
184
185/*----------------------------------------------------------------------------*/
186
187
188
189void pio_read_from_client_timeout( int fd, int maxbuf, int timeoutsec,
190        char buffer[], int *nbytes, int *timeout )
191
192/* Read message from client or timeout
193 *
194 * parameters of routine
195 * int        fd;       input; socket ID
196 * int        maxbuf;   input; maximum buffer length
197 * int        timeoutsec; input; maximum number of seconds to wait
198 * char       buffer[]; output; message read from socket
199 * int        *nbytes;  output; number of bytes read
200 * int        *timeout; output; timeout occurred
201 */
202{
203        /* local variables */
204        fd_set   set;             /* file descriptor set */
205        struct timeval stimeout;  /* timeout structure */
206
207        /* executable code */
208
209        if  (fd <= 0)  {*nbytes = 0;  return;}
210
211        FD_ZERO( &set );
212        FD_SET( fd, &set );
213        stimeout.tv_sec = timeoutsec;
214        stimeout.tv_usec = 0;
215
216        *timeout = !select( FD_SETSIZE, &set, NULL, NULL, &stimeout );
217
218        if  (*timeout)  {
219                *nbytes = 0;
220        } else {
221                *nbytes = read( fd, buffer, maxbuf );
222        } /*endif*/
223
224} /* end of pio_read_from_client_timeout */
225
226
227
228/*----------------------------------------------------------------------------*/
229
230
231
232int pio_term_found( char msg[], int *msglth )
233
234/* Finds and removes termination string
235 *
236 * parameters of routine
237 * char       msg[];     modify; message to check, term string removed
238 * int        *msglth;   modify; lenght of message
239 */
240{
241        /* local variables */
242        int      found;       /* term string fond */
243
244        /* executable code */
245
246        found = (*msglth >= cPio_TERMLTH
247                                && strcmp(msg+(*msglth)-cPio_TERMLTH,cPio_TERM) == 0);
248
249        if  (found)  {
250                msg[*msglth-cPio_TERMLTH] = '\0';
251                *msglth -= cPio_TERMLTH;
252        } /*endif*/
253
254        return (found);
255
256} /*end of pio_term_found */
257
258
259
260/*----------------------------------------------------------------------------*/
261
262
263
264int pio_make_socket( uint16_t port )
265
266/* Creates socket and returns its ID
267 *
268 * parameters of routine
269 * uint16_t   port; input; port number to use for connection
270 *                  returns socket ID
271 */
272{
273        /* local variables */
274        int      sock;            /* socket */
275        struct sockaddr_in name;  /* socket name (address) */
276
277        /* executable code */
278
279        /* Create the socket. */
280        sock = socket( PF_INET, SOCK_STREAM, 0 );
281        if  (sock < 0)  {
282                perror ("pio_make_socket (socket)");
283                if  (piov_log != NULL)
284                        fprintf( piov_log, "pio_make_socket: error creating socket\n" );
285                exit( EXIT_FAILURE );
286        } /*endif*/
287
288        /* Give the socket a name. */
289        name.sin_family = AF_INET;
290        name.sin_port = htons( port );
291        name.sin_addr.s_addr = htonl( INADDR_ANY );
292        if  (bind(sock,(struct sockaddr *) &name,sizeof(name)) < 0)  {
293                perror( "pio_make_socket (bind)" );
294                if  (piov_log != NULL)
295                        fprintf( piov_log, "pio_make_socket: error binding socket\n" );
296                exit( EXIT_FAILURE );
297        } /*endif*/
298
299        return sock;
300
301} /* end of pio_make_socket */
302
303
304
305/*----------------------------------------------------------------------------*/
306
307
308
309void pio_write_to_client( int fd, char msg[] )
310
311/* writes message to client
312 *
313 * parameters of routine
314 * int        fd; input; file descriptor (socket)
315 * char       msg[]; input; message text
316 */
317{
318        /* local variables */
319        int      nbytes;    /* number of bytes */
320
321        /* executable code */
322
323   nbytes = write (fd, msg, strlen(msg) + 1);
324   if  (nbytes < 0)  {
325                perror ("pio_write_to_client");
326                if  (piov_log != NULL)
327                        fprintf( piov_log, "pio_write_to_client: error writing to socket %d\n",
328                                fd );
329        } /*endif*/
330
331} /* end of write_to_server */
332
333
334
335/*----------------------------------------------------------------------------*/
336
337
338
339void pio_set_logfile( FILE *logf )
340
341/* Sets log file for debug messages
342 *
343 * parameters for routine
344 * FILE       *logf; input; logfile pointer
345 */
346{
347        /* executable code */
348
349        piov_log = logf;
350
351} /* end of pio_set_logfile */
352
353
354
355/*----------------------------------------------------------------------------*/
356
357
358
359void pio_send_file_to_socket( char fname[], int sock, int *status )
360
361/* Sends specified file to given socket
362 *
363 * parameters of routine
364 * char       fname[]; input; file to send
365 * int        sock;    input; socket ID
366 * int        *status; output; return status
367 */
368{
369        /* local variables */
370        FILE     *fp;                  /* pointer to input file */
371        char     line[cPio_MAXBUF+1];  /* current line of file */
372        int      slen;                 /* string length */
373
374        /* executable code */
375
376        fp = fopen( fname, "r" );
377        if  (fp == NULL)  {
378                *status = cPioE_FILE_OPEN;
379                return;
380        } /*endif*/
381
382        while  (fgets(line,cPio_MAXBUF,fp) != NULL)  {
383                slen = strlen( line );
384                if  (write( sock, line, slen ) != slen)  {
385                        *status = cPioE_SOCK_WRITE_ERR;
386                        perror( "pio_send_file_to_socket" );
387                        return;
388                } /*endif*/
389        } /*endwhile*/
390
391        fclose( fp );
392
393} /* end of pio_send_file_to_socket */
394
395
396
397/*----------------------------------------------------------------------------*/
Note: See TracBrowser for help on using the repository browser.