跨平台socket 简单实现

header

代码

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

代码
    void socket_init()
    { 
#ifdef _MSC_VER
        WORD version 
= MAKEWORD( 22 );
        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, 00 ));

    }

    
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, &bytesizeof (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个连接(客户端简单一些)

 

代码



    
int socket_num;
    
int conns = 0;
    
char buf[512];
    
int new_fd;
    fd_set fdsr;
    unsigned 
int fd_A[5];
    memset(fd_A, 
0sizeof(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, 000);

        
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();


 

posted @ 2010-06-26 04:04  史莱姆  阅读(2981)  评论(0编辑  收藏  举报