17 #if defined( WINDOWS ) 18 #define SOCKET_ERRNO( x ) WSA##x 19 #define socket_errno WSAGetLastError() 20 typedef int socklen_t;
24 #include <arpa/inet.h> 27 #include <netinet/in.h> 28 #include <netinet/tcp.h> 29 #include <sys/socket.h> 33 #define SOCKET_ERRNO( x ) x 34 #define socket_errno errno 54 WSAStartup( MAKEWORD( 1, 0 ), &dummy );
94 struct sockaddr client_addr;
95 socklen_t addrlen =
sizeof client_addr;
98 struct sockaddr_in* in_addr = (
struct sockaddr_in*)&client_addr;
99 if ( client_addr.sa_family == AF_INET )
100 return inet_ntoa( in_addr->sin_addr );
102 return "(display error)";
105 return "Error retrieving peer name";
128 _sck = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
135 INFO_PRINT <<
"Unable to open socket in Socket::open()\n";
139 struct sockaddr_in sin;
140 memset( &sin, 0,
sizeof sin );
141 sin.sin_family = AF_INET;
142 sin.sin_addr.s_addr = inet_addr( ipaddr );
143 sin.sin_port = htons( port );
146 int res = connect(
_sck, (
struct sockaddr*)&sin,
sizeof sin );
170 int res = setsockopt(
_sck, IPPROTO_TCP, TCP_NODELAY, (
const char*)&tcp_nodelay,
171 sizeof( tcp_nodelay ) );
174 throw std::runtime_error(
"Unable to setsockopt (TCP_NODELAY) on socket, res=" +
184 u_long nonblocking = 1;
185 int res = ioctlsocket( sck, FIONBIO, &nonblocking );
187 int flags = fcntl( sck, F_GETFL );
189 int res = fcntl( sck, F_SETFL, O_NONBLOCK );
193 throw std::runtime_error(
"Unable to set listening socket to nonblocking mode, res=" +
206 setsockopt( sck, SOL_SOCKET, SO_REUSEADDR, (
const char*)&reuse_opt,
sizeof( reuse_opt ) );
209 throw std::runtime_error(
"Unable to setsockopt (SO_REUSEADDR) on listening socket, res = " +
218 struct sockaddr_in local;
221 local.sin_family = AF_INET;
222 local.sin_addr.s_addr = INADDR_ANY;
224 local.sin_port = htons( port );
225 memset( local.sin_zero, 0,
sizeof( local.sin_zero ) );
227 _sck = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
237 if ( bind(
_sck, (
struct sockaddr*)&local,
sizeof( local ) ) == -1 )
253 struct timeval timeout = {0, 0};
259 "Select() implementation in Linux cant handle this many sockets at the same time." )
267 timeout.tv_sec = seconds;
268 timeout.tv_usec = useconds;
269 res =
::select( nfds, &fd, NULL, NULL, &timeout );
272 return ( res > 0 && FD_ISSET(
_sck, &fd ) );
292 struct sockaddr client_addr;
293 socklen_t addrlen =
sizeof client_addr;
299 newsocket.
setpeer( client_addr );
318 static char ErrorBuffer[80];
320 ErrVal = WSAGetLastError();
321 WSASetLastError( 0 );
341 if ( FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle( TEXT(
"wsock32" ) ), ErrVal,
342 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ErrorBuffer,
sizeof ErrorBuffer,
345 sprintf( ErrorBuffer,
"Unknown error code 0x%08x", ErrVal );
376 tv.tv_usec = waitms * 1000;
377 res =
::select( nfds, &fd, NULL, NULL, &tv );
387 else if ( res == -1 )
393 res = recv(
_sck, (
char*)ch, 1, 0 );
420 char* pdest = (
char*)vdest;
442 tv.tv_usec = waitms * 1000;
443 res =
::select( nfds, &fd, NULL, NULL, &tv );
453 else if ( res == -1 )
460 res = ::recv(
_sck, pdest, len, 0 );
465 INFO_PRINT.Format(
"\{R:{}[{}]\}\n" ) << res << len;
472 INFO_PRINT.Format(
"\{{:#X}\}\n" ) << (
unsigned char)( *tmp++ );
493 unsigned Socket::peek(
void* vdest,
unsigned len,
unsigned int wait_sec )
496 char* pdest = (
char*)vdest;
512 tv.tv_sec = wait_sec;
514 res =
::select( nfds, &fd, NULL, NULL, &tv );
524 else if ( res == -1 )
532 res = ::recv(
_sck, pdest, len, MSG_PEEK );
555 const char* cdata =
static_cast<const char*
>( vdata );
570 INFO_PRINT <<
"Socket::send() error: " << sckerr <<
"\n";
585 const char* cdata =
static_cast<const char*
>( vdata );
602 INFO_PRINT <<
"Socket::send_nowait() error: " << sckerr <<
"\n";
619 send( (
void*)s.c_str(),
static_cast<unsigned int>( s.length() ) );
631 shutdown(
_sck, SHUT_RDWR );
641 return ( s ==
"127.0.0.1" );
void write(const std::string &str)
bool recvdata(void *vdest, unsigned len, unsigned int waitms)
void apply_prebind_socket_options(SOCKET sck)
std::string decint(unsigned short v)
bool listen(unsigned short port)
std::string getpeername() const
bool open(const char *ipaddr, unsigned short port)
bool recvbyte(unsigned char *byte, unsigned int waitms)
#define passert_r(exp, reason)
unsigned peek(void *vdest, unsigned len, unsigned int waitms)
bool send_nowait(const void *vdata, unsigned datalen, unsigned *nsent)
bool accept(SOCKET *s, unsigned int mstimeout)
void setsocket(SOCKET sck)
struct sockaddr peer_address() const
void setpeer(struct sockaddr peer)
bool select(unsigned int seconds, unsigned int useconds)
void apply_socket_options(SOCKET sck)
void set_options(option opt)
void send(const void *data, unsigned length)
std::atomic< bool > exit_signalled