socket服务端select模式+管道+多线程,select可以替换为epoll

socket服务端select模式+管道+多线程,select可以替换为epoll

#include  " stdafx.h "

using   namespace  std;


#define  PORT 5006   /* Port that will be opened */
#define  BACKLOG 5   /* Number of allowed connections */
#define  MAXDATASIZE 4096

typedef map
< unsigned  int ,sockaddr_in >  socket_maptable_t;
bool  process_client( int  sockfd,sockaddr_in addr, char *  recvbuf,  int  len);

socket_maptable_t socket_maptable;
int  fds[ 2 ];


void *  dispatch_thread( void   * arg)
{
    
char  buf[MAXDATASIZE];
    arg 
=  NULL;
    pr_debug(
" fds[0]:%d,fds[1]:%d " ,fds[ 0 ],fds[ 1 ]);
    
while  ( 1 )
    {
        
int  readed  =  read(fds[ 0 ],buf,MAXDATASIZE);
        pr_debug(
" readed:%d\r\n%s " ,readed,buf);
    }
}

int  main()
{
    
int  sock_fd;
    ssize_t recv_size;
    fd_set read_set;
    fd_set all_set;
    
int  listen_fd;
    
int  connect_fd;
    
int  ready_size;
    socklen_t addr_size;
    sockaddr_in srv_addr;
    sockaddr_in addr;
    unsigned 
int  max_fd  =   0 ;
    
int  errcode;
    
    
char  recv_buf[MAXDATASIZE];

    
if  ((listen_fd  =  socket(AF_INET, SOCK_STREAM,  0 ))  ==   - 1 ) {
        pr_debug(
" Creating socket failed. " );
        exit(
1 );
    }

    
int  opt  =  SO_REUSEADDR;
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, 
& opt,  sizeof (opt));

    bzero(
& srv_addr, sizeof (srv_addr));
    srv_addr.sin_family
= AF_INET;
    srv_addr.sin_port
= htons(PORT);
    srv_addr.sin_addr.s_addr 
=  htonl (INADDR_ANY);
    
if  (bind(listen_fd, ( struct  sockaddr  * ) & srv_addr,  sizeof ( struct  sockaddr))  ==   - 1
    {
        pr_debug(
" Bind error. " );
        exit(
1 );
    }

    
if (listen(listen_fd,BACKLOG)  ==   - 1
    {
        pr_debug(
" listen() error\n " );
        exit(
1 );
    }


    
// 创建管道
    errcode  =  pipe(fds);
    
if  (errcode  <   0 )
    {
        pr_debug(
" pipe() error " );
        
return   - 1 ;
    }
    pr_debug(
" pipe() succeed,fds[0]:%d,fds[1]:%d " ,fds[ 0 ],fds[ 1 ]);


    
// 创建接收连接线程
    pthread_t dispatch_tid;
    
if  (pthread_create( & dispatch_tid, NULL, dispatch_thread, ( void * )NULL)) 
    {
        pr_debug(
" pthread_create() dispatch_thread error " );
        
return   - 1 ;
    }
    pr_debug(
" pthread_create() dispatch_thread succeed " );

    max_fd 
=  listen_fd;
    addr_size
= sizeof (sockaddr_in);

    FD_ZERO(
& all_set);
    FD_SET(listen_fd, 
& all_set);

    socket_maptable_t::iterator iter;

    
    
while ( 1 )
    {
        read_set 
=  all_set;
        ready_size 
=  select(max_fd + 1 & read_set, NULL, NULL, NULL);
        
if  ( FD_ISSET(listen_fd, & read_set) ) {
            connect_fd 
=  accept(listen_fd,( struct  sockaddr  * ) & addr, & addr_size);
            
if  (connect_fd  ==- 1  ) {
                pr_debug(
" accept() error\n " );
                
continue ;
            }
            socket_maptable[connect_fd]  
=  addr;
            max_fd 
=  connect_fd;
            FD_SET(connect_fd, 
& all_set);
            pr_debug(
" (%u) %s:%d connected,socket:%u " ,socket_maptable.size(),inet_ntoa(addr.sin_addr),ntohs(addr.sin_port),connect_fd);
        }

        
for  ( iter  =  socket_maptable.begin(); iter != socket_maptable.end(); iter ++ )
        {
            sock_fd 
=  iter -> first;
            addr 
=  iter -> second;
            
if  ( FD_ISSET(sock_fd, & read_set) )
            {
                recv_size 
=  recv(sock_fd, recv_buf, MAXDATASIZE, 0 );
                
bool  bRet  =  (recv_size  >   0 );
                bRet 
=  bRet  &&  process_client(sock_fd,addr,recv_buf,recv_size);
                
if  (  ! bRet) 
                {
                    close(sock_fd);
                    FD_CLR(sock_fd, 
& all_set);
                    socket_maptable.erase(sock_fd);
                    pr_debug(
" %s:%d disconnected\n " ,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port) );
                }
            }
        }
    }
    close(listen_fd);
}


bool  process_client( int  sockfd,sockaddr_in addr, char *  recvbuf,  int  len)
{
    
int  writed  =  write(fds[ 1 ],recvbuf,len);
    pr_debug(
" datalen:%d,writed:%d " ,len,writed);
    
return  (writed == len);
    
return   true ;
}

你可能感兴趣的:(socket服务端select模式+管道+多线程,select可以替换为epoll)