#include #include #include #include #include #include #include #include #include #include #ifndef NO_SIGCHLD_HANDLER #include void sigchld_handler( int a ) { while ( waitpid( -1, NULL, WNOHANG ) > 0 ); } #endif /* NO_SIGCHLD_HANDLER */ #define MYPORT 3490 #define BACKLOG 1 inline void doit( int connfd ) { char input; int recvd; while ( 1 ) { recvd = recv( connfd, &input, 1, 0 ); if ( recvd == -1 ) { perror( "recv" ); break; } else if ( recvd == 0 ) { struct sockaddr_in name; unsigned int sin_size = sizeof( struct sockaddr_in ); if ( getpeername( connfd, (struct sockaddr *) &name, &sin_size ) == -1 ) { perror( "getpeername" ); exit( 1 ); } printf( "server: closing connection %s:%d\n", inet_ntoa( name.sin_addr), ntohs( name.sin_port ) ); break; } if ( send( connfd, &input, 1, 0 ) == -1 ) { perror( "send" ); break; } } } inline void forkit( int listenfd, int connfd ) { int pid; if ( ( pid = fork() ) == 0 ) { close( listenfd ); doit( connfd ); close( connfd ); exit( 0 ); } else if ( pid == -1 ) { perror( "fork" ); } close( connfd ); } int main( void ) { int sockfd, new_fd; struct sockaddr_in my_addr; struct sockaddr_in their_addr; unsigned int sin_size; #ifndef NO_SIGCHLD_HANDLER void (*sigchld_bkp)(int) ; if ( ( sigchld_bkp = signal( SIGCHLD, sigchld_handler ) ) == SIG_ERR ) { fprintf( stderr, "ERROR: could not change "\ "signal SIGCHLD handler!\n" ); exit( 1 ); } #endif /* NO_SIGCHLD_HANDLER */ if ( ( sockfd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) { perror( "socket" ); exit( 1 ); } my_addr.sin_family = AF_INET; my_addr.sin_port = htons( MYPORT ); my_addr.sin_addr.s_addr = INADDR_ANY; memset( &( my_addr.sin_zero ), '\0', 8 ); if ( bind( sockfd, ( struct sockaddr * )&my_addr, sizeof( struct sockaddr ) ) == -1 ) { perror( "bind" ); exit( 1 ); } if ( listen( sockfd, BACKLOG ) == -1 ) { perror( "listen" ); exit( 1 ); } while( 1 ) { sin_size = sizeof( struct sockaddr_in ); if ( ( new_fd = accept( sockfd, ( struct sockaddr * )&their_addr, &sin_size ) ) == -1 ) { perror( "accept" ); continue; } printf( "server: got connection from %s:%d\n", inet_ntoa( their_addr.sin_addr ), ntohs( their_addr.sin_port) ); forkit( sockfd, new_fd ); } #ifndef NO_SIGCHLD_HANDLER signal( SIGCHLD, sigchld_bkp ); #endif /* NO_SIGCHLD_HANDLER */ return 0; } /* author: Gustavo Sverzut Barbieri (http://www.gustavobarbieri.com.br) */