linux Socket多路复用模式服务端 69.cpp

linux Socket多路复用模式服务端 69.cpp

//  File: 69.cpp
#include  < iostream >
#include 
< map >
#include 
< stdio.h >
#include 
< unistd.h >
#include 
< stdlib.h >
#include 
< math.h >
#include 
< string .h >  
#include 
< strings.h >
#include 
< sys / types.h >  
#include 
< sys / socket.h >  
#include 
< netinet / in .h >  
#include 
< arpa / inet.h >
#include 
< bitset >
using   namespace  std;
#define  PORT 1234   /* Port that will be opened */ 
#define  BACKLOG 5   /* Number of allowed connections */ 
#define  MAXDATASIZE 4096  

typedef map
< unsigned  int ,sockaddr_in >  connects;
void  process_cli( int  sockfd,sockaddr_in addr, char *  recvbuf,  int  len);


void  reverser( char *  szIn, char *  szOut,unsigned  int  nLen) 
{
 
for  ( int  i = 0 ;i < nLen;i ++ ) {
  szOut[i] 
=  szIn[nLen - i - 1 ];
 }
}

int  main() 

 connects connect_fds;
 
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 ;
 
char  recv_buf[MAXDATASIZE];

 
if  ((listen_fd  =  socket(AF_INET, SOCK_STREAM,  0 ))  ==   - 1 ) {
  perror(
" 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 ) { 
  perror(
" Bind error. " );
  exit(
1 ); 
 }    

 
if (listen(listen_fd,BACKLOG)  ==   - 1 ) {  
  perror(
" listen() error\n " ); 
  exit(
1 ); 
 } 
 max_fd 
=  listen_fd;
 addr_size
= sizeof (sockaddr_in); 
 
 FD_ZERO(
& all_set);
 FD_SET(listen_fd, 
& all_set);

 connects::iterator iter;

 printf(
" clients:(%u) ,current listen socket:%u\n " ,connect_fds.size(),listen_fd);
 
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  ) {
    perror(
" accept() error\n " ); 
    
continue
   }
   connect_fds[connect_fd]  
=  addr;
   max_fd 
=  connect_fd;
   FD_SET(connect_fd, 
& all_set);
   printf(
" clients:(%u) ,%s:%d connected ,connect socket:%u\n " ,connect_fds.size(),inet_ntoa(addr.sin_addr),ntohs(addr.sin_port),connect_fd);
  }

  
for  ( iter  =  connect_fds.begin(); iter != connect_fds.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 );
    
if  ( recv_size  ==   0 ) {
     close(sock_fd);
     FD_CLR(sock_fd, 
& all_set);
     connect_fds.erase(sock_fd);
     printf(
" %s:%d disconnected\n " ,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port) );
    } 
    
else  {
     process_cli(sock_fd,addr,recv_buf,recv_size);
    }
   }
  }
 }
 close(listen_fd);



void  process_cli( int  sockfd,sockaddr_in addr, char *  recvbuf,  int  len)
{
 
char  sendbuf[MAXDATASIZE];
 printf(
" Received %s:%d message: %s\n " ,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), recvbuf);
 reverser(recvbuf,sendbuf,len);
 printf(
" Send To  %s:%d message: %s\n " ,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), sendbuf);
 send(sockfd,sendbuf,len,
0 );
}

你可能感兴趣的:(linux Socket多路复用模式服务端 69.cpp)