select并行处理的一个简单示例
环境 AIX5.5 /C
头文件 public.h
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>
客户端 sockclient.c
#include "public.h"
int main( int arg, char ** argv )
{
struct sockaddr_in sockaddr;
int sockfd;
int n;
char buf[ 1024 ];
memset( buf, 0x00, sizeof( buf ));
sockfd = socket( AF_INET, SOCK_STREAM, 0 );
bzero( &sockaddr, sizeof( sockaddr ));
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons( 8006 );
inet_pton( AF_INET, argv[ 1 ], &sockaddr.sin_addr );
connect( sockfd, ( struct sockaddr * )&sockaddr, sizeof( struct sockaddr_in ));
fprintf( stdout, "sockfd is %d/n", sockfd );
while( 1 )
{
sleep( 5 );
write( sockfd, "33", 2 );
n = read( sockfd, buf, sizeof( buf ));
fprintf( stderr, "buf: [%s]/n", buf );
}
close( sockfd );
exit( 0 );
}
服务器 sockserver.c
#include "public.h"
#define MAXNTHREADS 20
void * thread_fun( void *arg )
{
int fd;
fd_set writefds;
fd_set readfds;
fd_set exfds;
int rc;
struct timeval tv;
char buf[ 1024 ];
fd = *( int * )arg;
fprintf( stdout,"in thread_fun is %d/n", fd );
FD_ZERO( &readfds );
FD_SET( fd, &readfds);
tv.tv_sec = 10;
tv.tv_usec = 0;
while( 1 )
{
FD_ZERO( &readfds );
FD_SET( fd, &readfds);
FD_ZERO( &exfds );
FD_SET( fd, &exfds);
tv.tv_sec = 10;
tv.tv_usec = 0;
fprintf( stdout," thread begin to select/n" );
rc = select( fd + 1 , &readfds, NULL, &exfds, NULL);
fprintf( stdout,"thread fd is %d/n",fd );
fprintf( stdout,"thread rc is %d/n",rc );
if( rc == 0 )
{
continue;
}
if( rc < 0 )
{
break;
}
if( FD_ISSET( fd, &exfds ))
{
fprintf( stdout,"fd_isset except is true /n");
return NULL;
}
if( FD_ISSET( fd, &readfds ))
{
int nn;
fprintf( stdout,"fd_isset read is true /n");
nn = read( fd, buf, 256 );
fprintf( stdout,"fd_isset read nn is %d /n", nn );
if( nn == 0 )
{
close( fd );
return NULL ;
}
memcpy( buf, "hello world/n/r", 13 );
write ( fd, buf, strlen( buf ));
continue;
}
close( fd );
return NULL;
}
}
int main( int argc, char ** argv )
{
struct sockaddr_in sockaddr;
struct sockaddr_in clientsockaddr;
int sockfd;
int clientfd;
socklen_t len;
int n;
char buf[ 1024 ];
pthread_t pthread[ MAXNTHREADS ];
int t_id[ MAXNTHREADS ];
int nthreads;
int sock_fds[ MAXNTHREADS ][ 2 ];
fd_set fds;
int rc;
struct timeval tv;
nthreads = 0;
memset( buf, 0x00, sizeof( buf ));
sockfd = socket( AF_INET, SOCK_STREAM, 0 );
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons( 8006 );
sockaddr.sin_addr.s_addr = htonl( INADDR_ANY );
bind( sockfd, ( struct sockaddr * )&sockaddr, sizeof( sockaddr ));
listen( sockfd, 10 );
pthread_setconcurrency( MAXNTHREADS );
FD_ZERO( &fds );
FD_SET( sockfd, &fds );
tv.tv_sec = 10;
tv.tv_usec = 0;
while( 1 )
{
fprintf( stdout, "begin to select/n" );
FD_ZERO( &fds );
FD_SET( sockfd, &fds );
rc = select( sockfd + 1, &fds, NULL, NULL, NULL );
if( rc == 0 )
{
fprintf( stdout, "rc == 0 /n" );
continue;
}
if( rc < 0 )
{
fprintf( stdout, "rc < 0 /n" );
}
if( FD_ISSET( sockfd, &fds ))
{
fprintf( stdout, "begin to accept client socket/n" );
clientfd = accept( sockfd, ( struct sockaddr * )&clientsockaddr, &len);
if( clientfd > 0 )
{
int rc;
fprintf( stdout,"create thread/n" );
rc = pthread_create( &pthread[ nthreads ], NULL, thread_fun, &clientfd );
if( rc == 0 )
{
fprintf( stdout,"main thread is %d/n", pthread[ nthreads ] );
sock_fds[ nthreads ][ 0 ] = clientfd;
sock_fds[ nthreads ][ 1 ] = pthread[ nthreads ];
nthreads++;
sock_fds[ nthreads ][ 0 ] = -1 ;
}
}
}
}
}
makefile
IFLAGS= -I $HOME
CC=cc -lpthread
EXE=sockclient
EXE1=sockserver
OBJECT=$(EXE)(sockclient.o)
OBJECT1=$(EXE1)(sockserver.o)
all:$(EXE) $(EXE1)