151 lines
3 KiB
C++
151 lines
3 KiB
C++
#include "socketio.h"
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
using namespace zutil;
|
|
|
|
SocketIO::SocketIO() : socket_id(-1){
|
|
memset( &address, 0, sizeof( address ) );
|
|
}
|
|
|
|
SocketIO::~SocketIO(){
|
|
if( is_valid() )
|
|
close( socket_id );
|
|
}
|
|
|
|
bool SocketIO::create(){
|
|
socket_id = socket( AF_INET, SOCK_STREAM, 0 );
|
|
|
|
if( !is_valid() )
|
|
return false;
|
|
|
|
|
|
// TIME_WAIT - argh
|
|
int on = 1;
|
|
if( setsockopt( socket_id, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on) ) == -1 )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SocketIO::bind( const int port ){
|
|
if ( !is_valid() ) {
|
|
return false;
|
|
}
|
|
|
|
address.sin_family = AF_INET;
|
|
address.sin_addr.s_addr = INADDR_ANY;
|
|
address.sin_port = htons( port );
|
|
|
|
int bind_return = ::bind( socket_id, (struct sockaddr*)&address, sizeof( address ) );
|
|
|
|
if( bind_return == -1 ){
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool SocketIO::listen() const{
|
|
if ( !is_valid() ){
|
|
return false;
|
|
}
|
|
|
|
int listen_return = ::listen( socket_id, MAX_CONNECTIONS );
|
|
|
|
if ( listen_return == -1 ){
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool SocketIO::accept( SocketIO& new_socket ) const{
|
|
int addr_length = sizeof( address );
|
|
new_socket.socket_id = ::accept( socket_id, (sockaddr*)&address, (socklen_t*) &addr_length );
|
|
|
|
if( new_socket.socket_id <= 0 )
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool SocketIO::write( const char c ) const{
|
|
return write( &c, 1 );
|
|
}
|
|
bool SocketIO::write( const string s ) const{
|
|
return write( s.c_str(), s.size() );
|
|
}
|
|
bool SocketIO::write( const char* buf, size_t len ) const{
|
|
int sent_bytes = send( socket_id, buf, len, MSG_PRIO);
|
|
if ( sent_bytes == -1 )
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
char SocketIO::read( ) const{
|
|
char c;
|
|
read( &c, 1 );
|
|
return c;
|
|
}
|
|
int SocketIO::read( string &s ) const{
|
|
s = "";
|
|
char buf [ SOCKET_BUFFER + 1 ];
|
|
|
|
int recv_bytes = read( buf, SOCKET_BUFFER );
|
|
if(recv_bytes > 0)
|
|
s = buf;
|
|
return recv_bytes;
|
|
}
|
|
int SocketIO::read( char* buf, size_t len ) const{
|
|
memset( buf, 0, len );
|
|
int recv_bytes = recv( socket_id, buf, len, 0 );
|
|
|
|
if( recv_bytes == -1 ){
|
|
cout << "status == -1 errno == " << errno << " in Socket::read\n";
|
|
return 0;
|
|
}
|
|
else if( recv_bytes == 0 ){
|
|
return 0;
|
|
}
|
|
else{
|
|
return recv_bytes;
|
|
}
|
|
}
|
|
|
|
bool SocketIO::connect( const string host, const int port ){
|
|
if ( !is_valid() ) return false;
|
|
|
|
address.sin_family = AF_INET;
|
|
address.sin_port = htons( port );
|
|
|
|
int status = inet_pton( AF_INET, host.c_str(), &address.sin_addr );
|
|
|
|
if ( errno == EAFNOSUPPORT )
|
|
return false;
|
|
|
|
status = ::connect( socket_id, (sockaddr*)&address, sizeof ( address ) );
|
|
|
|
if( status == 0 )
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
void SocketIO::set_non_blocking( const bool b ){
|
|
int opts;
|
|
opts = fcntl( socket_id, F_GETFL );
|
|
|
|
if( opts < 0 ){
|
|
return;
|
|
}
|
|
|
|
if( b )
|
|
opts = ( opts | O_NONBLOCK );
|
|
else
|
|
opts = ( opts & ~O_NONBLOCK );
|
|
|
|
fcntl ( socket_id, F_SETFL,opts );
|
|
|
|
}
|