#ifndef __PINET_H__
#define __PINET_H__
#ifndef __PPORT_H__
#include "pport.h"
#endif
#ifndef __PTYPES_H__
#include "ptypes.h"
#endif
#ifndef __PSTREAMS_H__
#include "pstreams.h"
#endif
#ifdef WIN32
# include <winsock2.h>
#else
# include <netdb.h>
# include <sys/types.h>
# include <sys/socket.h>
#endif
PTYPES_BEGIN
#ifdef _MSC_VER
#pragma pack(push, 4)
#endif
#if defined(WSAENOTSOCK) && !defined(ENOTSOCK)
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#define EALREADY WSAEALREADY
#define ENOTSOCK WSAENOTSOCK
#define EDESTADDRREQ WSAEDESTADDRREQ
#define EMSGSIZE WSAEMSGSIZE
#define EPROTOTYPE WSAEPROTOTYPE
#define ENOPROTOOPT WSAENOPROTOOPT
#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#define EOPNOTSUPP WSAEOPNOTSUPP
#define EPFNOSUPPORT WSAEPFNOSUPPORT
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#define EADDRINUSE WSAEADDRINUSE
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define ENETDOWN WSAENETDOWN
#define ENETUNREACH WSAENETUNREACH
#define ENETRESET WSAENETRESET
#define ECONNABORTED WSAECONNABORTED
#define ECONNRESET WSAECONNRESET
#define ENOBUFS WSAENOBUFS
#define EISCONN WSAEISCONN
#define ENOTCONN WSAENOTCONN
#define ESHUTDOWN WSAESHUTDOWN
#define ETOOMANYREFS WSAETOOMANYREFS
#define ETIMEDOUT WSAETIMEDOUT
#define ECONNREFUSED WSAECONNREFUSED
#define ELOOP WSAELOOP
#define EHOSTDOWN WSAEHOSTDOWN
#define EHOSTUNREACH WSAEHOSTUNREACH
#define EPROCLIM WSAEPROCLIM
#define EUSERS WSAEUSERS
#define EDQUOT WSAEDQUOT
#define ESTALE WSAESTALE
#define EREMOTE WSAEREMOTE
#define HOST_NOT_FOUND WSAHOST_NOT_FOUND
#define TRY_AGAIN WSATRY_AGAIN
#define NO_RECOVERY WSANO_RECOVERY
#define NO_DATA WSANO_DATA
#endif
#if defined(SD_RECEIVE) && !defined(SHUT_RD)
# define SHUT_RD SD_RECEIVE
# define SHUT_WR SD_SEND
# define SHUT_RDWR SD_BOTH
#endif
#ifndef SOMAXCONN
# define SOMAXCONN -1
#endif
typedef char* sockval_t;
#ifndef WIN32
# define closesocket close
#endif
#if (defined(__DARWIN__) && !defined(_SOCKLEN_T)) || defined(WIN32) || defined(__hpux)
typedef int psocklen;
#else
typedef socklen_t psocklen;
#endif
struct ipaddress
{
public:
union
{
uchar data[4];
ulong ldata;
};
ipaddress() {}
ipaddress(ulong a) { ldata = a; }
ipaddress(const ipaddress& a) { ldata = a.ldata; }
ipaddress(int a, int b, int c, int d);
ipaddress& operator= (ulong a) { ldata = a; return *this; }
ipaddress& operator= (const ipaddress& a) { ldata = a.ldata; return *this; }
uchar& operator [] (int i) { return data[i]; }
operator ulong() const { return ldata; }
};
extern ipaddress ipnone;
extern ipaddress ipany;
extern ipaddress ipbcast;
class ippeerinfo: public noncopyable
{
protected:
ipaddress ip;
string host;
int port;
void notfound();
friend bool psockname(int, ippeerinfo&);
public:
ippeerinfo();
ippeerinfo(ipaddress iip, const string& ihost, int iport);
ipaddress get_ip();
string get_host();
int get_port() { return port; }
void clear();
string asstring(bool showport) const;
};
string iptostring(ipaddress ip);
ipaddress phostbyname(const char* name);
string phostbyaddr(ipaddress ip);
string phostcname(const char* name);
int usockerrno();
const char* usockerrmsg(int code);
bool psockwait(int handle, int timeout);
bool psockname(int handle, ippeerinfo&);
const int IO_RESOLVING = 10;
const int IO_RESOLVED = 11;
const int IO_CONNECTING = 20;
const int IO_CONNECTED = 21;
class ipstream: public fdxstm, public ippeerinfo
{
friend class ipstmserver;
protected:
int svsocket;
#ifdef WIN32
// sockets are not compatible with file handles on Windows
virtual int dorawread(char* buf, int count);
virtual int dorawwrite(const char* buf, int count);
#endif
virtual int uerrno();
virtual const char* uerrmsg(int code);
virtual void doopen();
virtual large doseek(large newpos, ioseekmode mode);
virtual void doclose();
virtual void sockopt(int socket);
void closehandle();
public:
ipstream();
ipstream(ipaddress ip, int port);
ipstream(const char* host, int port);
ipstream(const string& host, int port);
virtual ~ipstream();
virtual int classid();
virtual string get_streamname();
bool waitfor(int timeout);
ipaddress get_myip();
int get_myport();
void set_ip(ipaddress);
void set_host(const string&);
void set_host(const char*);
void set_port(int);
};
class ipbindinfo: public unknown, public ippeerinfo
{
public:
int handle;
ipbindinfo(ipaddress iip, const string& ihost, int iport);
virtual ~ipbindinfo();
};
class ipsvbase: public unknown
{
protected:
int socktype;
bool active;
tobjlist<ipbindinfo> addrlist;
void error(ippeerinfo& peer, int code, const char* defmsg);
bool dopoll(int* i, int timeout);
void setupfds(void* set, int i);
virtual void open();
virtual void close();
virtual void dobind(ipbindinfo*) = 0;
virtual void sockopt(int socket);
public:
ipsvbase(int isocktype);
virtual ~ipsvbase();
int bind(ipaddress ip, int port);
int bindall(int port);
int get_addrcount() { return addrlist.get_count(); }
const ipbindinfo& get_addr(int i) { return *addrlist[i]; }
void clear();
};
class ipstmserver: public ipsvbase
{
protected:
virtual void dobind(ipbindinfo*);
public:
ipstmserver();
virtual ~ipstmserver();
bool poll(int i = -1, int timeout = 0);
bool serve(ipstream& client, int i = -1, int timeout = -1);
};
class ipmessage: public unknown, public ippeerinfo
{
protected:
int handle;
void error(int code, const char* msg);
void open();
void close();
virtual void sockopt(int socket);
public:
ipmessage();
ipmessage(ipaddress ip, int port);
ipmessage(const char* host, int port);
ipmessage(const string& host, int port);
virtual ~ipmessage();
void set_ip(ipaddress iip);
void set_host(const string&);
void set_host(const char*);
void set_port(int);
ipaddress get_myip();
int get_myport();
int get_handle() { return handle; }
bool waitfor(int timeout);
int receive(char* buf, int count, ipaddress& src);
int receive(char* buf, int count);
string receive(int max, ipaddress& src);
string receive(int max);
void send(const char* buf, int count);
void send(const string& s) { send(s, length(s)); }
};
class ipmsgserver: public ipsvbase, public ippeerinfo
{
protected:
int handle;
virtual void close();
virtual void dobind(ipbindinfo*);
public:
ipmsgserver();
virtual ~ipmsgserver();
int get_handle() { return handle; }
bool poll(int i = -1, int timeout = 0);
int receive(char* buf, int count);
string receive(int max);
void send(const char* buf, int count);
void send(const string& s) { send(s, length(s)); }
void sendto(const char* buf, int count, ipaddress ip, int port);
void sendto(const string& s, ipaddress ip, int port)
{ sendto(s, length(s), ip, port); }
};
#ifdef _MSC_VER
#pragma pack(pop)
#endif
PTYPES_END
#endif