跨平台socket 简单实现

header

ExpandedBlockStart.gif 代码

void  socket_init();
void  socket_term();
int  socket_create_acceptor( u_short port,  bool  reuse  =   false  );
int  socket_create_connector();
int  socket_connect(  int  s,  const   char *  address, u_short port );
int  socket_accept(  int  s );
int  socket_send(  int  s,  const   char *  msg,  int  length );
void  socket_close(  int  s );
bool  socket_disconnected(  int  s );
int  socket_setsockopt(  int  s,  int  opt );
int  socket_getsockopt(  int  s,  int  opt,  int &  optval );


cpp

ExpandedBlockStart.gif 代码
     void  socket_init()
    { 
#ifdef _MSC_VER
        WORD version 
=  MAKEWORD(  2 2  );
        WSADATA data;
        WSAStartup( version, 
& data );
#else
        
struct  sigaction sa;
        sa.sa_handler 
=  SIG_IGN;
        sigemptyset( 
& sa.sa_mask );
        sa.sa_flags 
=   0 ;
        sigaction( SIGPIPE, 
& sa,  0  );
#endif

    }

    
void  socket_term()
    {

#ifdef _MSC_VER
        WSACleanup();
#endif
    }

    
int  socket_create_acceptor(u_short port,  bool  reuse)
    {

        
int  socket  =  ( int )(::socket( PF_INET, SOCK_STREAM,  0  ));
        
if  ( socket  <   0  )  return   - 1 ;

        sockaddr_in address;
        socklen_t socklen;

        address.sin_family 
=  PF_INET;
        address.sin_port 
=  htons( port );
        address.sin_addr.s_addr 
=  INADDR_ANY;
        socklen 
=   sizeof ( address );
        
if ( reuse )
            socket_setsockopt( socket, SO_REUSEADDR );

        
int  result  =  bind( socket, reinterpret_cast  <  sockaddr *   >  (  & address ),
            socklen );
        
if  ( result  <   0  )  return   - 1 ;
        result 
=  listen( socket, SOMAXCONN );
        
if  ( result  <   0  )  return   - 1 ;
        
return  socket;

    }

    
int  socket_create_connector()
    {
        
return  ( int )(::socket( PF_INET, SOCK_STREAM, IPPROTO_TCP ));
    }

    
int  socket_connect(  int  socket,  const   char *  address, u_short port )
    {

        
const   char *  hostname  =  socket_hostname( address );
        
if ( hostname  ==   0  )  return   - 1 ;

        sockaddr_in addr;
        addr.sin_family 
=  PF_INET;
        addr.sin_port 
=  htons( port );
        addr.sin_addr.s_addr 
=  inet_addr( hostname );

        
int  result  =  connect( socket, reinterpret_cast  <  sockaddr *   >  (  & addr ),
            
sizeof ( addr ) );

        
return  result;

    }

    
int  socket_accept(  int  s )
    {

        
if  (  ! socket_isValid( s ) )  return   - 1 ;
        
return  ( int )(accept( s,  0 0  ));

    }

    
int  socket_send(  int  s,  const   char *  msg,  int  length )
    {
        
return  send( s, msg, length,  0  );
    }

    
void  socket_close(  int  s )
    {

        shutdown( s, 
2  );
#ifdef _MSC_VER
        closesocket( s );
#else
        close( s );
#endif

    }

    
bool  socket_disconnected(  int  s )
    {

        
char   byte ;
        
return  ::recv (s,  & byte sizeof  ( byte ), MSG_PEEK)  <=   0 ;

    }

    
int  socket_setsockopt(  int  s,  int  opt )
    {

        
int  level  =  SOL_SOCKET;
        
if ( opt  ==  TCP_NODELAY )
            level 
=  IPPROTO_TCP;

#ifdef _MSC_VER
        BOOL optval 
=  TRUE;
        
return  ::setsockopt( s, level, opt,
            ( 
char *  )  &  optval,  sizeof ( optval ) );
#else
        
int  optval  =   1 ;
        
return  ::setsockopt( s, level, opt,
            
& optval,  sizeof ( optval ) );
#endif
    }

    
int  socket_getsockopt(  int  s,  int  opt,  int &  optval )
    {

        
int  level  =  SOL_SOCKET;
        
if ( opt  ==  TCP_NODELAY )
            level 
=  IPPROTO_TCP;

#ifdef _MSC_VER
        
int  length;
#else
        socklen_t length;
#endif

        
return  ::getsockopt( s, level, opt, 
            ( 
char *  )  &  optval,  &  length );

    }


服务器端 跨平台select 使用, 例子中支持最多5个连接(客户端简单一些)

 

ExpandedBlockStart.gif 代码



    
int  socket_num;
    
int  conns  =   0 ;
    
char  buf[ 512 ];
    
int  new_fd;
    fd_set fdsr;
    unsigned 
int  fd_A[ 5 ];
    memset(fd_A, 
0 sizeof (fd_A));

    socket_init();

    socket_num 
=  socket_create_acceptor( 14001 );

    
while ( ! shutdown){
        FD_ZERO( 
& fdsr );
        FD_SET((u_int)socket_num,
& fdsr);

        
for  ( int  i  =   0 ; i  <   5 ; i ++ )
        {
            
if  (fd_A[i]  !=   0 )
                FD_SET(fd_A[i], 
& fdsr);
        }

        
int  result  =  select( FD_SETSIZE,  & fdsr,  0 0 0 );

        
if  ( result  <   0  )
            
break ;
        
else   if  (result  ==   0 )
            
continue ;

        
//  check every fd in the set
         for  ( int  i  =   0 ; i  <  conns; i ++ )
        {
            
if  (FD_ISSET(fd_A[i],  & fdsr))
            {
                
int  ret  =  recv(fd_A[i], buf,  sizeof (buf),  0 );
                
if  (ret  <=   0 )
                {
                    socket_close(fd_A[i]);
                    FD_CLR(fd_A[i], 
& fdsr);
                    fd_A[i] 
=   0 ;
                }
                
else
                {
                    
// handle message
                }
            }
        }
        
if  (FD_ISSET(socket_num,  & fdsr))
        {
            
// handle new connection
            new_fd  =  socket_accept(socket_num);
            
if  (new_fd  <=   0 )
                
continue ;
            
if  (conns  <   5 )
                fd_A[conns
++ =  new_fd;
            
else
                socket_close(new_fd);
        }

    }
    
for  ( int  i  =   0 ; i  <   5 ; i ++ )
    {
        
if  (fd_A[i]  !=   0 )
            socket_close(fd_A[i]);
    }
    socket_term();


 

转载于:https://www.cnblogs.com/slime/archive/2010/06/26/1765609.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值