git-svn-id: svn://db.shs.com.ru/pip@542 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-09-05 15:20:33 +00:00
parent b67512d38c
commit 6f54f501cd
7 changed files with 324 additions and 131 deletions

View File

@@ -61,6 +61,43 @@ public:
DisonnectOnTimeout /** Disconnect TCP connection on read timeout expired. Disabled by default */ = 0x20
};
//! \brief IPv4 network address, ip and port
class Address {
friend class PIEthernet;
friend inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v);
friend inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v);
public:
//! Contructs %Address with binary representation of ip and port
Address(uint ip = 0, ushort port = 0);
Address(const PIString & ip_port);
Address(const PIString & ip, ushort port);
uint ip() const {return ip_;}
ushort port() const {return port_;}
PIString ipString() const;
PIString toString() const;
void setIP(uint ip);
void setIP(const PIString & ip);
void setPort(ushort port);
void set(const PIString & ip_port);
void set(const PIString & ip, ushort port);
void set(uint ip, ushort port);
void clear();
//! Resolve hostname "host" and return it IPv4 address or "0.0.0.0" on error
static PIString resolve(const PIString & host);
static void splitIPPort(const PIString & ipp, PIString * ip, int * port);
private:
void initIP(const PIString & _ip);
union {
uint ip_;
uchar ip_b[4];
};
ushort port_;
};
//! Contructs %PIEthernet with type "type", read address "ip_port" and parameters "params"
explicit PIEthernet(Type type, const PIString & ip_port = PIString(), const PIFlags<Parameters> params = PIEthernet::ReuseAddress | PIEthernet::MulticastLoop | PIEthernet::KeepConnection);
@@ -68,59 +105,65 @@ public:
//! Set read address
void setReadAddress(const PIString & ip, int port) {setPath(ip + PIStringAscii(":") + PIString::fromNumber(port));}
void setReadAddress(const PIString & ip, int port) {addr_r.set(ip, port); setPath(addr_r.toString());}
//! Set read address in format "i.i.i.i:p"
void setReadAddress(const PIString & ip_port) {setPath(ip_port);}
void setReadAddress(const PIString & ip_port) {addr_r.set(ip_port); setPath(addr_r.toString());}
//! Set read address
void setReadAddress(const Address & addr) {addr_r = addr; setPath(addr_r.toString());}
//! Set read IP
void setReadIP(const PIString & ip) {parseAddress(path(), &ip_, &port_); setPath(ip + PIStringAscii(":") + PIString::fromNumber(port_));}
void setReadIP(const PIString & ip) {addr_r.setIP(ip); setPath(addr_r.toString());}
//! Set read port
void setReadPort(int port) {parseAddress(path(), &ip_, &port_); setPath(ip_ + PIStringAscii(":") + PIString::fromNumber(port));}
void setReadPort(int port) {addr_r.setPort(port); setPath(addr_r.toString());}
//! Set send address
void setSendAddress(const PIString & ip, int port) {ip_s = ip; port_s = port;}
void setSendAddress(const PIString & ip, int port) {addr_s.set(ip, port);}
//! Set send address in format "i.i.i.i:p"
void setSendAddress(const PIString & ip_port) {parseAddress(ip_port, &ip_s, &port_s);}
void setSendAddress(const PIString & ip_port) {addr_s.set(ip_port);}
//! Set send address
void setSendAddress(const Address & addr) {addr_s = addr;}
//! Set send IP
void setSendIP(const PIString & ip) {ip_s = ip;}
void setSendIP(const PIString & ip) {addr_s.setIP(ip);}
//! Set send port
void setSendPort(int port) {port_s = port;}
void setSendPort(int port) {addr_s.setPort(port);}
//! Returns read address in format "i.i.i.i:p"
PIString readAddress() const {return path();}
Address readAddress() const {return addr_r;}
//! Returns read IP
PIString readIP() const {parseAddress(path(), &ip_, &port_); return ip_;}
PIString readIP() const {return addr_r.ipString();}
//! Returns read port
int readPort() const {parseAddress(path(), &ip_, &port_); return port_;}
int readPort() const {return addr_r.port();}
//! Returns send address in format "i.i.i.i:p"
PIString sendAddress() const {return ip_s + PIStringAscii(":") + PIString::fromNumber(port_s);}
Address sendAddress() const {return addr_s;}
//! Returns send IP
PIString sendIP() const {return ip_s;}
PIString sendIP() const {return addr_s.ipString();}
//! Returns send port
int sendPort() const {return port_s;}
int sendPort() const {return addr_s.port();}
//! Returns address of last received UDP packet in format "i.i.i.i:p"
PIString lastReadAddress() const {return ip_r + PIStringAscii(":") + PIString::fromNumber(port_r);}
Address lastReadAddress() const {return addr_lr;}
//! Returns IP of last received UDP packet
PIString lastReadIP() const {return ip_r;}
PIString lastReadIP() const {return addr_lr.ipString();}
//! Returns port of last received UDP packet
int lastReadPort() const {return port_r;}
int lastReadPort() const {return addr_lr.port();}
//! Set parameters to "parameters_". You should to reopen %PIEthernet to apply them
@@ -210,19 +253,25 @@ public:
bool send(const void * data, int size, bool threaded = false) {if (threaded) {writeThreaded(data, size); return true;} return (write(data, size) == size);}
//! Send data "data" with size "size" to address "ip":"port"
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {ip_s = ip; port_s = port; if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
bool send(const PIString & ip, int port, const void * data, int size, bool threaded = false) {addr_s.set(ip, port); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" with size "size" to address "ip_port"
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
bool send(const PIString & ip_port, const void * data, int size, bool threaded = false) {addr_s.set(ip_port); if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" with size "size" to address "addr"
bool send(const Address & addr, const void * data, int size, bool threaded = false) {addr_s = addr; if (threaded) {writeThreaded(data, size); return true;} return send(data, size);}
//! Send data "data" to address \a sendAddress() for UDP or \a readAddress() for TCP_Client
bool send(const PIByteArray & data, bool threaded = false) {if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
//! Send data "data" to address "ip":"port" for UDP
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {ip_s = ip; port_s = port; if (threaded) {writeThreaded(data); return true;} return send(data);}
bool send(const PIString & ip, int port, const PIByteArray & data, bool threaded = false) {addr_s.set(ip, port); if (threaded) {writeThreaded(data); return true;} return send(data);}
//! Send data "data" to address "ip_port" for UDP
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {parseAddress(ip_port, &ip_s, &port_s); if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
bool send(const PIString & ip_port, const PIByteArray & data, bool threaded = false) {addr_s.set(ip_port); if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
//! Send data "data" to address "addr" for UDP
bool send(const Address & addr, const PIByteArray & data, bool threaded = false) {addr_s = addr; if (threaded) {writeThreaded(data); return true;} return (write(data) == data.size_s());}
virtual bool canWrite() const {return mode() & WriteOnly;}
@@ -317,19 +366,17 @@ public:
//! Returns all system network interfaces
static InterfaceList interfaces();
static PIString interfaceAddress(const PIString & interface_);
static PIEthernet::Address interfaceAddress(const PIString & interface_);
//! Returns all system network IP addresses
static PIStringList allAddresses();
//! Resolve hostname "host" and return it IPv4 address or "0.0.0.0" on error
static PIString resolve(const PIString & host);
static PIVector<PIEthernet::Address> allAddresses();
static void parseAddress(const PIString & ipp, PIString * ip, int * port);
static PIString macFromBytes(const PIByteArray & mac);
static PIByteArray macToBytes(const PIString & mac);
static PIString applyMask(const PIString & ip, const PIString & mask);
static Address applyMask(const Address & ip, const Address & mask);
static PIString getBroadcast(const PIString & ip, const PIString & mask);
static Address getBroadcast(const Address & ip, const Address & mask);
//! \events
//! \{
@@ -396,9 +443,8 @@ protected:
PRIVATE_DECLARATION
int sock, sock_s;
mutable int port_, port_s, port_r;
bool connected_, connecting_, listen_threaded, server_bounded;
mutable PIString ip_, ip_s, ip_r;
mutable Address addr_r, addr_s, addr_lr;
PIThread server_thread_;
PIMutex clients_mutex;
PIVector<PIEthernet * > clients_;
@@ -425,5 +471,11 @@ private:
inline bool operator <(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name < v1.name);}
inline bool operator ==(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name == v1.name && v0.address == v1.address && v0.netmask == v1.netmask);}
inline bool operator !=(const PIEthernet::Interface & v0, const PIEthernet::Interface & v1) {return (v0.name != v1.name || v0.address != v1.address || v0.netmask != v1.netmask);}
inline PICout operator <<(PICout s, const PIEthernet::Address & v) {s.setControl(0, true); s << "Address(" << v.toString() << ")"; s.restoreControl(); return s;}
inline bool operator ==(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() == v1.ip() && v0.port() == v1.port());}
inline bool operator !=(const PIEthernet::Address & v0, const PIEthernet::Address & v1) {return (v0.ip() != v1.ip() || v0.port() != v1.port());}
inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v) {s << v.ip_ << v.port_; return s;}
inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v) {s >> v.ip_ >> v.port_; return s;}
#endif // PIETHERNET_H