跨平台socket 简单实现
header
![](https://images.cnblogs.com/OutliningIndicators/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
![](https://images.cnblogs.com/OutliningIndicators/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 );
}
{
#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://images.cnblogs.com/OutliningIndicators/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();