多进程并发服务器
设计流程
框架一(使用信号回收僵尸进程)
void handler ( int sig)
{ while ( waitpid ( - 1 , NULL , WNOHANG) > 0 ) ;
} int main ( )
{ siganl ( 17 , handler) ; server = socket ( ) ; bind ( ) ; listen ( ) ; while ( 1 ) { client = accept ( ) ; if ( fork ( ) == 0 ) { close ( server) ; while ( 1 ) { recv ( ) ; send ( ) ; } close ( client) ; exit ( 0 ) ; } close ( client) ; } close ( server) ;
}
实例
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/select.h>
# include <sys/wait.h>
# include <time.h>
# include <fcntl.h>
# include <pthread.h>
# include <semaphore.h>
# include <signal.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <sys/shm.h>
# include <sys/sem.h>
# include <errno.h> # define LOG ( s) printf ( "[%s] {%s:%d} %s \n" , __DATE__ , __FILE__ , __LINE__ , s) ; void cil ( int client, struct sockaddr_in caddr) ; void handler ( int sig)
{ while ( waitpid ( - 1 , NULL , WNOHANG) > 0 ) ;
} int main ( int argc, char * argv[ ] )
{ signal ( 17 , handler) ; int server = - 1 ; if ( ( server = socket ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) { LOG ( "socket error" ) ; return - 1 ; } struct sockaddr_in saddr = { 0 } ; saddr. sin_family = AF_INET; saddr. sin_port = htons ( 8888 ) ; saddr. sin_addr. s_addr = htonl ( INADDR_ANY) ; if ( bind ( server, ( struct sockaddr * ) & saddr, sizeof ( saddr) ) == - 1 ) { LOG ( "bind error" ) ; return - 1 ; } if ( listen ( server, 5 ) == - 1 ) { LOG ( "listen error" ) ; return - 1 ; } puts ( "Tcp server start success" ) ; int client = - 1 ; struct sockaddr_in caddr = { 0 } ; socklen_t len = sizeof ( caddr) ; pid_t pid = - 1 ; while ( 1 ) { if ( ( client = accept ( server, ( struct sockaddr * ) & caddr, & len) ) == - 1 ) { LOG ( "accpet error" ) ; return - 1 ; } printf ( "[%s/%d] client已上线\n" , inet_ntoa ( caddr. sin_addr) , ntohl ( caddr. sin_port) ) ; if ( ( pid = fork ( ) ) < 0 ) { LOG ( "fork error" ) ; return - 1 ; } else if ( pid == 0 ) { cil ( client, caddr) ; exit ( 0 ) ; } close ( client) ; } close ( server) ; return 0 ;
} void cil ( int client, struct sockaddr_in caddr)
{ char buf[ 128 ] = "" ; int res = 0 ; while ( 1 ) { bzero ( buf, sizeof ( buf) ) ; if ( ( res = read ( client, buf, sizeof ( buf) ) ) < 0 ) { LOG ( "read error" ) ; break ; } else if ( res == 0 ) { printf ( "[%s/%d] client已下线\n" , inet_ntoa ( caddr. sin_addr) , ntohl ( caddr. sin_port) ) ; close ( client) ; break ; } printf ( "[%s/%d] client: %s\n" , inet_ntoa ( caddr. sin_addr) , ntohl ( caddr. sin_port) , buf) ; bzero ( buf, sizeof ( buf) ) ; strcpy ( buf, "ok" ) ; if ( write ( client, buf, sizeof ( buf) ) < 0 ) { LOG ( "write error" ) ; break ; } } }
框架二(使用孤儿进程机制避免僵尸进程产生)
int main ( )
{ server = socket ( ) ; bind ( ) ; listen ( ) ; while ( 1 ) { if ( ( pid = fork ( ) ) == 0 ) { client = accept ( ) ; if ( pid = fork ( ) == 0 ) { while ( 1 ) { recv ( ) ; send ( ) ; } close ( client) ; exit ( 0 ) ; } else if ( pid > 0 ) { close ( server) ; close ( client) ; exit ( 0 ) ; } } else if ( pid > 0 ) { while ( waitpid ( ) == pid) } } close ( server) ;
}
实例
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/select.h>
# include <sys/wait.h>
# include <time.h>
# include <fcntl.h>
# include <pthread.h>
# include <semaphore.h>
# include <signal.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <sys/shm.h>
# include <sys/sem.h>
# include <errno.h> # define LOG ( s) printf ( "[%s] {%s:%d} %s\n" , __DATE__ , __FILE__ , __LINE__ , s) ; void deal_cil_msg ( int client, struct sockaddr_in caddr) ; int main ( int argc, char * argv[ ] )
{ int server = 0 ; if ( ( server = socket ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) { LOG ( "socket error" ) ; return - 1 ; } struct sockaddr_in saddr = { 0 } ; saddr. sin_family = AF_INET; saddr. sin_port = htons ( 8888 ) ; saddr. sin_addr. s_addr = htonl ( INADDR_ANY) ; if ( bind ( server, ( struct sockaddr * ) & saddr, sizeof ( saddr) ) == - 1 ) { LOG ( "bind error" ) ; return - 1 ; } if ( listen ( server, 5 ) == - 1 ) { LOG ( "listen error" ) ; return - 1 ; } puts ( "server start success" ) ; struct sockaddr_in caddr = { 0 } ; int client = 0 ; socklen_t asize = sizeof ( caddr) ; pid_t pid = - 1 ; int status = 0 ; while ( 1 ) { pid = fork ( ) ; if ( pid < 0 ) { LOG ( "fork error" ) ; return - 1 ; } if ( pid == 0 ) { if ( ( client = accept ( server, ( struct sockaddr * ) & caddr, & asize) ) == - 1 ) { LOG ( "accept error" ) ; return - 1 ; } printf ( "[%s/%d]client已上线\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) ) ; pid = fork ( ) ; if ( pid < 0 ) { LOG ( "fork error" ) ; return - 1 ; } else if ( pid == 0 ) { deal_cil_msg ( client, caddr) ; close ( client) ; exit ( 0 ) ; } else if ( pid > 0 ) { close ( server) ; close ( client) ; exit ( 0 ) ; } } else if ( pid > 0 ) { printf ( "wait child = %d\n" , pid) ; while ( waitpid ( pid, & status, 0 ) == pid) { printf ( "Parent is over - child: %d, status = %x\n" , pid, status) ; } } } close ( server) ; return 0 ;
} void deal_cil_msg ( int client, struct sockaddr_in caddr)
{ char buf[ 128 ] = " " ; while ( 1 ) { int len = 0 ; bzero ( buf, sizeof ( buf) ) ; if ( ( len = recv ( client, buf, sizeof ( buf) , 0 ) ) < 0 ) { LOG ( "recv error" ) ; } else if ( len == 0 ) { printf ( "[%s/%d]client已下线\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) ) ; break ; } printf ( "[%s/%d]client: %s\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) , buf) ; bzero ( buf, sizeof ( buf) ) ; strcpy ( buf, "ok" ) ; write ( client, buf, len) ; } }
多线程并发服务器
设计流程
typedef struct
{ int client; struct sockaddr_in caddr;
} Client_msg; int main ( )
{ server = socket ( ) ; bind ( ) ; listen ( ) ; while ( 1 ) { client = accpet ( ) ; pthread_create ( ) ; while ( 1 ) { } pthread_detach ( ) ; } close ( server) ;
}
实例
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <sys/select.h>
# include <sys/wait.h>
# include <time.h>
# include <fcntl.h>
# include <pthread.h>
# include <semaphore.h>
# include <signal.h>
# include <sys/ipc.h>
# include <sys/msg.h>
# include <sys/shm.h>
# include <sys/sem.h>
# include <errno.h> # define LOG ( s) printf ( "[%s] {%s:%d} %s \n" , __DATE__ , __FILE__ , __LINE__ , s) ; void * cil ( void * arg) ;
typedef struct
{ int client; struct sockaddr_in caddr;
} Cli_msg; int main ( int argc, char * argv[ ] )
{ int server = - 1 ; if ( ( server = socket ( AF_INET, SOCK_STREAM, 0 ) ) == - 1 ) { LOG ( "socket error" ) ; return - 1 ; } struct sockaddr_in saddr = { 0 } ; saddr. sin_family = AF_INET; saddr. sin_port = htons ( 8899 ) ; saddr. sin_addr. s_addr = htonl ( INADDR_ANY) ; if ( bind ( server, ( struct sockaddr * ) & saddr, sizeof ( saddr) ) == - 1 ) { LOG ( "bind error" ) ; return - 1 ; } if ( listen ( server, 5 ) == - 1 ) { LOG ( "listen error" ) ; return - 1 ; } puts ( "tcp server start success" ) ; struct sockaddr_in caddr = { 0 } ; socklen_t len = sizeof ( caddr) ; pthread_t tid = - 1 ; int client = - 1 ; Cli_msg cli_msg; while ( 1 ) { if ( ( client = accept ( server, ( struct sockaddr * ) & caddr, & len) ) == - 1 ) { LOG ( "accept error" ) ; return - 1 ; } printf ( "[%s/%d]client已上线\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) ) ; cli_msg. client = client; cli_msg. caddr = caddr; if ( pthread_create ( & tid, NULL , cil, & cli_msg) != 0 ) { LOG ( "pthread_create error" ) ; return - 1 ; } pthread_detach ( tid) ; } close ( server) ; return 0 ;
} void * cil ( void * arg)
{ int client = ( ( Cli_msg* ) arg) -> client; struct sockaddr_in caddr = ( ( Cli_msg* ) arg) -> caddr; char buf[ 128 ] = "" ; int res = 0 ; while ( 1 ) { bzero ( buf, sizeof ( buf) ) ; if ( ( res = read ( client, buf, sizeof ( buf) ) ) < 0 ) { LOG ( "read error" ) ; break ; } else if ( res == 0 ) { printf ( "[%s/%d]client已下线\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) ) ; close ( client) ; pthread_exit ( NULL ) ; } printf ( "[%s/%d]client: %s\n" , inet_ntoa ( caddr. sin_addr) , ntohs ( caddr. sin_port) , buf) ; bzero ( buf, sizeof ( buf) ) ; strcpy ( buf, "ok" ) ; if ( write ( client, buf, sizeof ( buf) ) < 0 ) { LOG ( "write error" ) ; break ; } } }