header
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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 );
}
{
#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个连接(客户端简单一些)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.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();