/* echo-server-nofork-fdopen.c -- 受け取った文字列をそのまま返すサーバ(fork無し版) ~yas/syspro/ipc/echo-server-nofork-fdopen.c */ #include "coins-syspro.c" extern void echo_server( int portno, int ip_version ); extern void echo_receive_request_and_send_reply( int com ); extern int echo_receive_request( char *line, size_t size, FILE *in ); extern void echo_send_reply( char *line, FILE *out ); int main( int argc, char *argv[] ) { int portno, ip_version; if( !(argc == 2 || argc==3) ) { fprintf(stderr,"Usage: %s portno {ipversion}\n",argv[0] ); exit( 1 ); } portno = strtol( argv[1],0,10 ); if( argc == 3 ) ip_version = strtol( argv[2],0,10 ); else ip_version = 46; /* Both IPv4 and IPv6 by default */ echo_server( portno, ip_version ); } void echo_server( int portno, int ip_version ) { int acc,com ; acc = tcp_acc_port( portno, ip_version ); if( acc<0 ) exit( 1 ); print_my_host_port( portno ); tcp_sockaddr_print( acc ); while( 1 ) { printf("[%d] accepting incoming connections (acc==%d) ...\n", getpid(),acc ); if( (com = accept( acc,0,0 )) < 0 ) { perror("accept"); exit( -1 ); } printf("[%d] connection (fd==%d) from ",getpid(),com ); tcp_peeraddr_print( com ); echo_receive_request_and_send_reply( com ); } } #define BUFFERSIZE 1024 void echo_receive_request_and_send_reply( int com ) { char line[BUFFERSIZE] ; int rcount ; int wcount ; FILE *in, *out ; if( fdopen_sock(com,&in,&out) < 0 ) { perror("fdopen"); exit( 1 ); /* exit when no memory */ } while( (rcount=echo_receive_request(line,BUFFERSIZE,in))>0 ) { printf("[%d] received (fd==%d) %d bytes, [%s]\n", getpid(),com,rcount,line ); echo_send_reply( line,out ); } if( rcount < 0 ) perror("fgets"); printf("[%d] connection (fd==%d) closed.\n",getpid(),com ); fclose( in ); fclose( out ); } int echo_receive_request( char *line, size_t size, FILE *in ) { if( fgets( line,size,in ) ) { return( strlen(line) ); } else { if( ferror(in) ) return( -1 ); else return( 0 ); } } void echo_send_reply( char *line, FILE *out ) { fprintf(out,"%s",line ); }