TCP并发服务器的多进程实现与多线程实现
一、 TCP并发服务器的多进程实现
代码
# include <my_head.h> # define SERVER_IP "192.168.125.11"
# define SERVER_PORT 6666
int deal_client_message ( int new_sfd, struct sockaddr_in client_info) ;
void callBack_zembie ( int sig) ; int main ( int argc, const char * argv[ ] )
{ if ( signal ( SIGCHLD, callBack_zembie) < 0 ) { ERR_MSG ( "signal" ) ; return - 1 ; } int sfd = socket ( AF_INET, SOCK_STREAM, 0 ) ; if ( sfd < 0 ) { ERR_MSG ( "socket" ) ; return - 1 ; } struct sockaddr_in server_info; server_info. sin_addr. s_addr = inet_addr ( SERVER_IP) ; server_info. sin_port = htons ( SERVER_PORT) ; server_info. sin_family = AF_INET; if ( bind ( sfd, ( struct sockaddr * ) & server_info, sizeof ( server_info) ) < 0 ) { ERR_MSG ( "bind" ) ; return - 1 ; } if ( listen ( sfd, 128 ) < 0 ) { ERR_MSG ( "listen" ) ; return - 1 ; } struct sockaddr_in client_info; socklen_t len = sizeof ( client_info) ; int new_sfd; pid_t cpid = - 1 ; while ( 1 ) { new_sfd = accept ( sfd, ( struct sockaddr * ) & client_info, & len) ; if ( new_sfd < 0 ) { ERR_MSG ( "accept" ) ; return - 1 ; } printf ( "[%s : %d]已连接 new_fd = %d \n" , inet_ntoa ( client_info. sin_addr) , ntohs ( client_info. sin_port) , new_sfd) ; cpid = fork ( ) ; if ( 0 == cpid) { close ( sfd) ; deal_client_message ( new_sfd, client_info) ; close ( new_sfd) ; exit ( 0 ) ; } else if ( cpid < 0 ) { ERR_MSG ( "fork" ) ; return - 1 ; } close ( new_sfd) ; } close ( sfd) ; return 0 ;
}
void callBack_zembie ( int sig)
{ while ( waitpid ( - 1 , NULL , WNOHANG) > 0 ) ;
}
int deal_client_message ( int new_sfd, struct sockaddr_in client_info)
{ char buff[ 128 ] ; ssize_t res = - 1 ; while ( 1 ) { bzero ( buff, sizeof ( buff) ) ; res = recv ( new_sfd, buff, sizeof ( buff) , 0 ) ; if ( res < 0 ) { ERR_MSG ( "recv" ) ; break ; } else if ( 0 == res) { printf ( "[%s : %d] 已掉线\n" , inet_ntoa ( client_info. sin_addr) , ntohs ( client_info. sin_port) ) ; break ; } printf ( "[%s : %d][message : %s]\n" , inet_ntoa ( client_info. sin_addr) , ntohs ( client_info. sin_port) , buff) ; if ( ! strcmp ( buff, "exit" ) ) { printf ( "[%s : %d] 断开链接\n" , inet_ntoa ( client_info. sin_addr) , ntohs ( client_info. sin_port) ) ; break ; } strcat ( buff, "---" ) ; if ( send ( new_sfd, buff, sizeof ( buff) , 0 ) < 0 ) { ERR_MSG ( "send" ) ; break ; } } close ( new_sfd) ; return 0 ;
}
二、 TCP并发服务器的多线程实现
# include <my_head.h> # define SERVER_IP "192.168.125.11"
# define SERVER_PORT 6666 struct client_information
{ int new_sfd; struct sockaddr_in info;
} ;
void * thread1 ( void * arg) ; int main ( int argc, const char * argv[ ] )
{ int sfd = socket ( AF_INET, SOCK_STREAM, 0 ) ; if ( sfd < 0 ) { ERR_MSG ( "sfd" ) ; return - 1 ; } struct sockaddr_in server_info; server_info. sin_addr. s_addr = inet_addr ( SERVER_IP) ; server_info. sin_port = htons ( SERVER_PORT) ; server_info. sin_family = AF_INET; if ( bind ( sfd, ( struct sockaddr * ) & server_info, sizeof ( server_info) ) < 0 ) { ERR_MSG ( "bind" ) ; return - 1 ; } if ( listen ( sfd, 128 ) < 0 ) { ERR_MSG ( "listen" ) ; return - 1 ; } struct client_information client_info; socklen_t len = sizeof ( client_info. info) ; pthread_t tid; while ( 1 ) { client_info. new_sfd = accept ( sfd, ( struct sockaddr * ) & ( client_info. info) , & len) ; if ( client_info. new_sfd < 0 ) { ERR_MSG ( "accept" ) ; return - 1 ; } printf ( "[%s : %d]已连接 new_fd = %d \n" , inet_ntoa ( client_info. info. sin_addr) , ntohs ( client_info. info. sin_port) , client_info. new_sfd) ; if ( pthread_create ( & tid, NULL , thread1, & client_info) < 0 ) { fprintf ( stderr , "线程创建出错 __%d__\n" , __LINE__ ) ; return - 1 ; } pthread_detach ( tid) ; } close ( client_info. new_sfd) ; close ( sfd) ; return 0 ;
}
void * thread1 ( void * arg)
{ struct client_information client_info = * ( ( struct client_information * ) arg) ; ssize_t res = - 1 ; char buff[ 128 ] ; while ( 1 ) { bzero ( buff, sizeof ( buff) ) ; res = recv ( client_info. new_sfd, buff, sizeof ( buff) , 0 ) ; if ( res < 0 ) { ERR_MSG ( "recv" ) ; break ; } else if ( 0 == res) { printf ( "[%s : %d] 已掉线\n" , inet_ntoa ( client_info. info. sin_addr) , ntohs ( client_info. info. sin_port) ) ; break ; } printf ( "[%s : %d][message : %s]\n" , inet_ntoa ( client_info. info. sin_addr) , ntohs ( client_info. info. sin_port) , buff) ; if ( ! strcmp ( buff, "exit" ) ) { printf ( "[%s : %d] 断开链接\n" , inet_ntoa ( client_info. info. sin_addr) , ntohs ( client_info. info. sin_port) ) ; break ; } strcat ( buff, "---" ) ; if ( send ( client_info. new_sfd, buff, sizeof ( buff) , 0 ) < 0 ) { ERR_MSG ( "send" ) ; break ; } } close ( client_info. new_sfd) ; pthread_exit ( NULL ) ;
}