多进程并发服务器
设计流程
框架一(使用信号回收僵尸进程)
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 ;
}
}
}