Linux下网络编程-简易多线程并发服务器和客户端
简易多线程并发服务器:
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <arpa/inet.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <pthread.h>
# define BUF_SIZE 100
# define MAX_CLNT 256
int clnt_cnt= 0 ;
int clnt_socks[ MAX_CLNT] ;
pthread_mutex_t mutx;
void * handle_clnt ( void * arg) ;
void send_msg ( const char * msg, int len) ;
void error_handling ( const char * msg) ;
int main ( int argc, char * argv[ ] )
{
int serv_sock, clnt_sock;
struct sockaddr_in serv_adr, clnt_adr;
socklen_t clnt_adr_sz;
pthread_t t_id;
if ( argc!= 2 )
{
printf ( "Usage : %s <port>\n" , argv[ 0 ] ) ;
exit ( 1 ) ;
}
pthread_mutex_init ( & mutx, NULL ) ;
serv_sock= socket ( PF_INET, SOCK_STREAM, 0 ) ;
memset ( & serv_adr, 0 , sizeof ( serv_adr) ) ;
serv_adr. sin_family= AF_INET;
serv_adr. sin_addr. s_addr= htonl ( INADDR_ANY) ;
serv_adr. sin_port= htons ( atoi ( argv[ 1 ] ) ) ;
if ( bind ( serv_sock, ( struct sockaddr * ) & serv_adr, sizeof ( serv_adr) ) == - 1 )
error_handling ( "bind() error" ) ;
if ( listen ( serv_sock, 5 ) == - 1 )
error_handling ( "listen() error" ) ;
while ( 1 )
{
clnt_adr_sz= sizeof ( clnt_adr) ;
clnt_sock= accept ( serv_sock, ( struct sockaddr * ) & clnt_adr, & clnt_adr_sz) ;
if ( clnt_sock== - 1 )
{
error_handling ( "accept error!" ) ;
}
pthread_mutex_lock ( & mutx) ;
clnt_socks[ clnt_cnt++ ] = clnt_sock;
pthread_mutex_unlock ( & mutx) ;
pthread_create ( & t_id, NULL , handle_clnt, & clnt_socks[ clnt_cnt- 1 ] ) ;
printf ( "Connected client IP: %s \n" , inet_ntoa ( clnt_adr. sin_addr) ) ;
}
close ( serv_sock) ;
return 0 ;
}
void error_handling ( const char * msg)
{
fputs ( msg, stderr ) ;
fputc ( '\n' , stderr ) ;
exit ( 1 ) ;
}
void * handle_clnt ( void * arg)
{
pthread_detach ( pthread_self ( ) ) ;
int clnt_sock= * ( int * ) arg;
char msg[ BUF_SIZE] = "" ;
ssize_t str_len= 0 ;
while ( ( str_len= read ( clnt_sock, msg, sizeof ( msg) ) ) != 0 )
send_msg ( msg, str_len) ;
pthread_mutex_lock ( & mutx) ;
for ( int i= 0 ; i< clnt_cnt; i++ )
{
if ( clnt_sock== clnt_socks[ i] )
{
while ( i++ < clnt_cnt- 1 )
{
clnt_socks[ i] = clnt_socks[ i+ 1 ] ;
}
break ;
}
}
clnt_cnt-- ;
pthread_mutex_unlock ( & mutx) ;
close ( clnt_sock) ;
pthread_exit ( NULL ) ;
}
void send_msg ( const char * msg, int len)
{
pthread_mutex_lock ( & mutx) ;
for ( int i= 0 ; i< clnt_cnt; i++ )
{
write ( clnt_socks[ i] , msg, len) ;
}
pthread_mutex_unlock ( & mutx) ;
}
简易多线程并发客户端:
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <arpa/inet.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <pthread.h>
# define BUF_SIZE 100
# define NAME_SIZE 20
char name[ NAME_SIZE] = "[DEFAULT]" ;
char msg[ BUF_SIZE] ;
void * send_msg ( void * arg) ;
void * recv_msg ( void * arg) ;
void error_handling ( const char * msg) ;
int main ( int argc, char * argv[ ] )
{
int sock;
struct sockaddr_in serv_addr;
pthread_t snd_thread, rcv_thread;
void * thread_return;
if ( argc!= 4 )
{
printf ( "Usage : %s <IP> <port> <name>\n" , argv[ 0 ] ) ;
exit ( 1 ) ;
}
sprintf ( name, "[%s]" , argv[ 3 ] ) ;
sock= socket ( PF_INET, SOCK_STREAM, 0 ) ;
memset ( & serv_addr, 0 , sizeof ( serv_addr) ) ;
serv_addr. sin_family= AF_INET;
serv_addr. sin_addr. s_addr= inet_addr ( argv[ 1 ] ) ;
serv_addr. sin_port= htons ( atoi ( argv[ 2 ] ) ) ;
if ( connect ( sock, ( struct sockaddr * ) & serv_addr, sizeof ( serv_addr) ) == - 1 )
error_handling ( "connect() error" ) ;
pthread_create ( & snd_thread, NULL , send_msg, ( void * ) & sock) ;
pthread_create ( & rcv_thread, NULL , recv_msg, ( void * ) & sock) ;
pthread_join ( snd_thread, & thread_return) ;
pthread_join ( rcv_thread, & thread_return) ;
close ( sock) ;
return 0 ;
}
void * send_msg ( void * arg)
{
int sock= * ( int * ) arg;
char name_msg[ NAME_SIZE+ BUF_SIZE] ;
while ( 1 )
{
fgets ( msg, BUF_SIZE, stdin ) ;
if ( ! strcmp ( msg, "q\n" ) || ! strcmp ( msg, "Q\n" ) )
{
close ( sock) ;
exit ( 0 ) ;
}
sprintf ( name_msg, "%s %s" , name, msg) ;
write ( sock, name_msg, strlen ( name_msg) ) ;
}
return NULL ;
}
void * recv_msg ( void * arg)
{
int sock= * ( int * ) arg;
char name_msg[ NAME_SIZE+ BUF_SIZE] ;
int str_len;
while ( 1 )
{
str_len= read ( sock, name_msg, NAME_SIZE+ BUF_SIZE- 1 ) ;
if ( str_len== - 1 )
{
return ( void * ) - 1 ;
}
name_msg[ str_len] = 0 ;
fputs ( name_msg, stdout ) ;
}
return NULL ;
}
void error_handling ( const char * msg)
{
fputs ( msg, stderr ) ;
fputc ( '\n' , stderr ) ;
exit ( 1 ) ;
}