Implement comparison and hashing in NetAddress. Clean up Socket_Address code a bit.

This commit is contained in:
rdb 2014-10-27 12:09:56 +00:00
parent c7a3a7d4ff
commit 241adfe34d
5 changed files with 361 additions and 283 deletions

View File

@ -17,7 +17,7 @@
buffered_datagramreader.h buffered_datagramreader.i \
ringbuffer.h ringbuffer.i socket_ip.h \
socket_tcp_listen.h time_accumulator.h time_out.h \
socket_address.h \
socket_address.I socket_address.h \
socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
socket_base.h socket_selector.h \
socket_udp.h \
@ -42,7 +42,7 @@
ringbuffer.h ringbuffer.i socket_ip.h socket_tcp_listen.h \
time_accumulator.h time_out.h \
buffered_datagramreader.h buffered_datagramreader.i \
socket_address.h \
socket_address.I socket_address.h \
socket_portable.h time_base.h time_span.h buffered_datagramwriter.h \
socket_base.h socket_selector.h \
socket_udp.h \

View File

@ -0,0 +1,278 @@
// Filename: socket_address.I
// Created by: rdb (19Oct14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// Function: Socket_Address::GetIPAdddressRaw
// Access: Public
// Description: Return a RAW sockaddr_in
//////////////////////////////////////////////////////////////
INLINE unsigned long Socket_Address::
GetIPAddressRaw() const {
return _addr.sin_addr.s_addr;
}
///////////////////////////////////////////////////////////////////
// Function: Socket_Address
// Access: Published
// Description: Constructor that lets us set a port value
////////////////////////////////////////////////////////////////////
INLINE Socket_Address::
Socket_Address(unsigned short port) {
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(port);
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::Copy constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE Socket_Address::
Socket_Address(const Socket_Address &inaddr) {
_addr.sin_family = inaddr._addr.sin_family;
_addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
_addr.sin_port = inaddr._addr.sin_port;
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE Socket_Address::
Socket_Address(const AddressType &inaddr) {
_addr.sin_family = inaddr.sin_family;
_addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
_addr.sin_port = inaddr.sin_port;
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::~Destructor
// Access: Published
// Description: Normal Destructor
////////////////////////////////////////////////////////////////////
INLINE Socket_Address::
~Socket_Address() {
}
//////////////////////////////////////////////////////////////
// Function: Socket_Address::operator ==
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
operator == (const Socket_Address &in) const {
return ((_addr.sin_family == in._addr.sin_family) &&
(_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
(_addr.sin_port == in._addr.sin_port));
}
//////////////////////////////////////////////////////////////
// Function: Socket_Address::operator !=
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
operator != (const Socket_Address &in) const {
return ((_addr.sin_family != in._addr.sin_family) ||
(_addr.sin_addr.s_addr != in._addr.sin_addr.s_addr) ||
(_addr.sin_port != in._addr.sin_port));
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::set_broadcast
// Access: Published
// Description: Set to the broadcast address and a specified port
////////////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_broadcast(int port) {
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = 0xffffffff;
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::set_any_IP
// Access: Published
// Description: Set to any address and a specified port
////////////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_any_IP(int port) {
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::set_port
// Access: Published
// Description: Set to a specified port
////////////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_port(int port) {
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::clear
// Access: Published
// Description: Set the internal values to a suitable known value
////////////////////////////////////////////////////////////////////
INLINE void Socket_Address::
clear() {
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(0);
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::get_port
// Access: Published
// Description: Get the port portion as an integer
////////////////////////////////////////////////////////////////////
INLINE unsigned short Socket_Address::
get_port() const {
return ntohs(_addr.sin_port);
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::get_ip
// Access: Published
// Description: Return the IP address portion in dot notation string
////////////////////////////////////////////////////////////////////
INLINE std::string Socket_Address::
get_ip() const {
return std::string(inet_ntoa(_addr.sin_addr));
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::get_ip_port
// Access: Published
// Description: Return the ip address/port in dot notation string
////////////////////////////////////////////////////////////////////
INLINE std::string Socket_Address::
get_ip_port() const {
char buf1[100]; // 100 is more than enough for any ip address:port combo..
sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
return std::string(buf1);
}
////////////////////////////////////////////////////////////////////
// Function: Socket_Address::set_host
// Access: Published
// Description: This function will take a port and string-based
// TCP address and initialize the address with this
// information. Returns true on success; on failure,
// it returns false and the address may be undefined.
////////////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_host(const std::string &hostname, int port) {
struct hostent *hp = NULL;
//
// hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
//
// * HACK * ??
if (hostname == "255.255.255.255") {
return set_broadcast(port);
}
//
//
PN_uint32 addr = (long)inet_addr(hostname.c_str());
if (addr == INADDR_NONE) {
hp = gethostbyname(hostname.c_str());
if (hp == NULL) {
return false;
} else {
memcpy(&_addr.sin_addr, hp->h_addr_list[0], (unsigned int) hp->h_length);
}
} else {
memcpy(&_addr.sin_addr, &addr, sizeof(addr));
}
_addr.sin_port = htons(port);
_addr.sin_family = AF_INET;
return true;
}
//////////////////////////////////////////////////////////////
// Function: Socket_Address::set_host
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_host(const std::string &hostname) {
std::string::size_type pos = hostname.find(':');
if (pos == std::string::npos)
return false;
std::string host = hostname.substr(0, pos);
std::string port = hostname.substr(pos + 1, 100);;
int port_dig = atoi(port.c_str());
return set_host(host, port_dig);
}
//////////////////////////////////////////////////////////////
// Function: Socket_Address::set_host
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
set_host(PN_uint32 in_hostname, int port) {
memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
_addr.sin_port = htons(port);
_addr.sin_family = AF_INET;
return true;
}
//////////////////////////////////////////////////////////////
// Function: <
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
operator < (const Socket_Address &in) const {
if (_addr.sin_port < in._addr.sin_port)
return true;
if (_addr.sin_port > in._addr.sin_port)
return false;
if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
return true;
if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
return false;
return (_addr.sin_family < in._addr.sin_family);
}
//////////////////////////////////////////////////////////////
// Function: is_mcast_range
// Access: Published
// Description: True if the address is in the multicast range.
//////////////////////////////////////////////////////////////
INLINE bool Socket_Address::
is_mcast_range(void) const {
PN_uint32 address = ntohl(_addr.sin_addr.s_addr);
//224.0.0.0-239.255.255.255 .. e0,ef
return (address >= 0xe0000000 && address < 0xefffffff);
}

View File

@ -1,5 +1,5 @@
#ifndef __SOCKET_ADDRESS_H__
#define __SOCKET_ADDRESS_H__
#ifndef SOCKET_ADDRESS_H
#define SOCKET_ADDRESS_H
#include "pandabase.h"
#include "numeric_types.h"
@ -12,277 +12,43 @@
// communication layer
//
//////////////////////////////
class EXPCL_PANDA_NATIVENET Socket_Address
{
class EXPCL_PANDA_NATIVENET Socket_Address {
public:
typedef struct sockaddr_in AddressType;
Socket_Address(const AddressType &inaddr);
AddressType & GetAddressInfo() { return _addr; }
const AddressType & GetAddressInfo() const { return _addr; }
typedef struct sockaddr_in AddressType;
Socket_Address(const AddressType &inaddr);
AddressType &GetAddressInfo() { return _addr; }
const AddressType &GetAddressInfo() const { return _addr; }
PUBLISHED:
inline Socket_Address(short port = 0);
inline Socket_Address(const Socket_Address &inaddr);
INLINE Socket_Address(unsigned short port = 0);
INLINE Socket_Address(const Socket_Address &inaddr);
inline virtual ~Socket_Address();
inline bool set_any_IP(int port);
inline bool set_port(int port);
inline bool set_broadcast(int port);
inline bool set_host(const std::string &hostname, int port) ;
inline bool set_host(const std::string &hostname) ;
inline bool set_host(unsigned int ip4adr, int port);
inline void clear();
inline unsigned short get_port() const;
inline std::string get_ip() const ;
inline std::string get_ip_port() const;
inline unsigned long GetIPAddressRaw() const;
inline bool operator== (const Socket_Address &in) const;
inline bool operator < (const Socket_Address &in) const;
INLINE virtual ~Socket_Address();
inline bool isMcastRange();
INLINE bool set_any_IP(int port);
INLINE bool set_port(int port);
INLINE bool set_broadcast(int port);
INLINE bool set_host(const std::string &hostname, int port) ;
INLINE bool set_host(const std::string &hostname) ;
INLINE bool set_host(unsigned int ip4adr, int port);
INLINE void clear();
INLINE unsigned short get_port() const;
INLINE std::string get_ip() const ;
INLINE std::string get_ip_port() const;
INLINE unsigned long GetIPAddressRaw() const;
INLINE bool operator ==(const Socket_Address &in) const;
INLINE bool operator !=(const Socket_Address &in) const;
INLINE bool operator < (const Socket_Address &in) const;
INLINE bool is_mcast_range() const;
private:
AddressType _addr;
AddressType _addr;
};
//////////////////////////////////////////////////////////////
// Function name : Socket_Address::GetIPAdddressRaw
// Description : Return a RAW sockaddr_in
//////////////////////////////////////////////////////////////
inline unsigned long Socket_Address::GetIPAddressRaw() const
{
return _addr.sin_addr.s_addr;
}
#include "socket_address.I"
///////////////////////////////////////////////////////////////////
// Function name : Socket_Address
// Description : Constructor that lets us set a port value
////////////////////////////////////////////////////////////////////
inline Socket_Address::Socket_Address(short port)
{
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(port);
}
////////////////////////////////////////////////////////////////////
// Function name : Socket_Address Constructor
// Description : Copy Constructor
////////////////////////////////////////////////////////////////////
inline Socket_Address::Socket_Address(const Socket_Address &inaddr)
{
_addr.sin_family = inaddr._addr.sin_family;
_addr.sin_addr.s_addr = inaddr._addr.sin_addr.s_addr;
_addr.sin_port = inaddr._addr.sin_port;
}
inline Socket_Address::Socket_Address(const AddressType &inaddr)
{
_addr.sin_family = inaddr.sin_family;
_addr.sin_addr.s_addr = inaddr.sin_addr.s_addr;
_addr.sin_port = inaddr.sin_port;
}
////////////////////////////////////////////////////////////////////
// Function name : ~Socket_Address::Socket_Address
// Description : Normal Destructor
////////////////////////////////////////////////////////////////////
inline Socket_Address::~Socket_Address()
{}
//////////////////////////////////////////////////////////////
// Function name : Socket_Address::operator==
// Description : Allow for normal == operation on a address item..
// Will simplify the use in sorted containers..
//////////////////////////////////////////////////////////////
inline bool Socket_Address::operator==(const Socket_Address &in) const
{
return ((_addr.sin_family == in._addr.sin_family) &&
(_addr.sin_addr.s_addr == in._addr.sin_addr.s_addr) &&
(_addr.sin_port == in._addr.sin_port)
);
}
////////////////////////////////////////////////////////////////////
// Function name : set_broadcast
// Description : Set to the broadcast address and a specified port
////////////////////////////////////////////////////////////////////
inline bool Socket_Address::set_broadcast(int port)
{
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = 0xffffffff;
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : set_any_IP
// Description : Set to any address and a specified port
////////////////////////////////////////////////////////////////////
inline bool Socket_Address::set_any_IP(int port)
{
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : set_port
// Description : Set to a specified port
////////////////////////////////////////////////////////////////////
inline bool Socket_Address::set_port(int port)
{
_addr.sin_port = htons(port);
return true;
}
////////////////////////////////////////////////////////////////////
// Function name : clear
// Description : Set the internal values to a suitable known value
////////////////////////////////////////////////////////////////////
inline void Socket_Address::clear()
{
_addr.sin_family = AF_INET;
_addr.sin_addr.s_addr = INADDR_ANY;
_addr.sin_port = htons(0);
}
////////////////////////////////////////////////////////////////////
// Function name : get_port
// Description : Get the port portion as an integer
////////////////////////////////////////////////////////////////////
inline unsigned short Socket_Address::get_port() const
{
return ntohs(_addr.sin_port);
}
////////////////////////////////////////////////////////////////////
// Function name : get_ip
// Description : Return the ip address portion in dot notation string
////////////////////////////////////////////////////////////////////
inline std::string Socket_Address::get_ip() const
{
return std::string(inet_ntoa(_addr.sin_addr));
}
////////////////////////////////////////////////////////////////////
// Function name : get_ip_port
// Description : Return the ip address/port in dot notation string
////////////////////////////////////////////////////////////////////
inline std::string Socket_Address::get_ip_port() const
{
char buf1[100]; // 100 is more than enough for any ip address:port combo..
sprintf(buf1, "%s:%d", inet_ntoa(_addr.sin_addr), get_port());
return std::string(buf1);
}
////////////////////////////////////////////////////////////////////
// Function name : set_host
// Description : this function will take a port and string-based tcp address and initialize
// the address with the information
//
// Return type : bool (address is undefined after an error)
////////////////////////////////////////////////////////////////////
inline bool Socket_Address::set_host(const std::string &hostname, int port)
{
struct hostent *hp = NULL;
//
// hmm inet_addr does not resolve 255.255.255.255 on ME/98 ??
//
// * HACK * ??
if(hostname == "255.255.255.255")
return set_broadcast(port);
//
//
PN_uint32 addr = (long)inet_addr (hostname.c_str());
if(addr == INADDR_NONE)
{
hp = gethostbyname(hostname.c_str());
if(hp== NULL)
return false;
else
memcpy(&(_addr.sin_addr),hp->h_addr_list[0] , (unsigned int) hp->h_length);
}
else
(void) memcpy(&_addr.sin_addr,&addr,sizeof(addr));
_addr.sin_port = htons(port);
_addr.sin_family = AF_INET;
return true;
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Address::set_host
// Description :
//////////////////////////////////////////////////////////////
inline bool Socket_Address::set_host(const std::string &hostname)
{
std::string::size_type pos = hostname.find(':');
if (pos == std::string::npos)
return false;
std::string host = hostname.substr(0, pos);
std::string port = hostname.substr(pos + 1, 100);;
int port_dig = atoi(port.c_str());
return set_host(host, port_dig);
}
//////////////////////////////////////////////////////////////
// Function name : Socket_Address::set_host
// Description :
//////////////////////////////////////////////////////////////
inline bool Socket_Address::set_host(PN_uint32 in_hostname, int port)
{
memcpy(&_addr.sin_addr, &in_hostname, sizeof(in_hostname));
_addr.sin_port = htons(port);
_addr.sin_family = AF_INET;
return true;
}
//////////////////////////////////////////////////////////////
// Function name : <
// Description :
//////////////////////////////////////////////////////////////
inline bool Socket_Address::operator < (const Socket_Address &in) const
{
if (_addr.sin_port < in._addr.sin_port)
return true;
if (_addr.sin_port > in._addr.sin_port)
return false;
if (_addr.sin_addr.s_addr < in._addr.sin_addr.s_addr)
return true;
if (_addr.sin_addr.s_addr > in._addr.sin_addr.s_addr)
return false;
return (_addr.sin_family < in._addr.sin_family);
}
//////////////////////////////////////////////////////////////
// Function name : isMcastRange
// Description : return true if the address is in the mcast range.
//////////////////////////////////////////////////////////////
inline bool Socket_Address::isMcastRange(void)
{
PN_uint32 address = ntohl(_addr.sin_addr.s_addr);
//224.0.0.0-239.255.255.255 .. e0,ef
if(address >= 0xe0000000 && address < 0xefffffff)
return true;
return false;
}
#endif //__SOCKET_ADDRESS_H__
#endif // SOCKET_ADDRESS_H

View File

@ -18,7 +18,7 @@
////////////////////////////////////////////////////////////////////
// Function: NetAddress::Constructor
// Access: Public
// Access: Published
// Description: Constructs an unspecified address.
////////////////////////////////////////////////////////////////////
NetAddress::
@ -27,7 +27,7 @@ NetAddress() {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::Constructor
// Access: Public
// Access: Published
// Description: Constructs an address from a given Socket_Address.
// Normally, this constructor should not be used by user
// code; instead, create a default NetAddress and use
@ -40,7 +40,7 @@ NetAddress(const Socket_Address &addr) : _addr(addr) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::set_any
// Access: Public
// Access: Published
// Description: Sets the address up to refer to a particular port,
// but not to any particular IP. Returns true if
// successful, false otherwise (currently, this only
@ -53,7 +53,7 @@ set_any(int port) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::set_localhost
// Access: Public
// Access: Published
// Description: Sets the address up to refer to a particular port,
// on this host.
////////////////////////////////////////////////////////////////////
@ -64,7 +64,7 @@ set_localhost(int port) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::set_broadcast
// Access: Public
// Access: Published
// Description: Sets the address to the broadcast address.
////////////////////////////////////////////////////////////////////
bool NetAddress::
@ -74,7 +74,7 @@ set_broadcast(int port) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::set_host
// Access: Public
// Access: Published
// Description: Sets the address up to refer to a particular port
// on a particular host. Returns true if the hostname
// is known, false otherwise.
@ -86,7 +86,7 @@ set_host(const string &hostname, int port) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::clear
// Access: Public
// Access: Published
// Description: Resets the NetAddress to its initial state.
////////////////////////////////////////////////////////////////////
void NetAddress::
@ -96,7 +96,7 @@ clear() {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::get_port
// Access: Public
// Access: Published
// Description: Returns the port number to which this address refers.
////////////////////////////////////////////////////////////////////
int NetAddress::
@ -106,7 +106,7 @@ get_port() const {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::set_port
// Access: Public
// Access: Published
// Description: Resets the port number without otherwise changing the
// address.
////////////////////////////////////////////////////////////////////
@ -117,7 +117,7 @@ set_port(int port) {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::get_ip_string
// Access: Public
// Access: Published
// Description: Returns the IP address to which this address refers,
// formatted as a string.
////////////////////////////////////////////////////////////////////
@ -128,7 +128,7 @@ get_ip_string() const {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::get_ip
// Access: Public
// Access: Published
// Description: Returns the IP address to which this address refers,
// as a 32-bit integer, in host byte order.
////////////////////////////////////////////////////////////////////
@ -139,7 +139,7 @@ get_ip() const {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::get_ip_component
// Access: Public
// Access: Published
// Description: Returns the nth 8-bit component of the IP address.
// An IP address has four components; component 0 is the
// first (leftmost), and component 3 is the last
@ -156,7 +156,7 @@ get_ip_component(int n) const {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::get_addr
// Access: Public
// Access: Published
// Description: Returns the Socket_Address for this address.
////////////////////////////////////////////////////////////////////
const Socket_Address &NetAddress::
@ -166,10 +166,40 @@ get_addr() const {
////////////////////////////////////////////////////////////////////
// Function: NetAddress::output
// Access: Public
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void NetAddress::
output(ostream &out) const {
out << get_ip_string();
}
//////////////////////////////////////////////////////////////
// Function: NetAddress::get_hash
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
size_t NetAddress::
get_hash() const {
return (size_t)(((int)get_ip()) ^ ((int)get_port() << 16));
}
//////////////////////////////////////////////////////////////
// Function: NetAddress::operator ==
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
bool NetAddress::
operator == (const NetAddress &other) const {
return _addr == other._addr;
}
//////////////////////////////////////////////////////////////
// Function: NetAddress::operator !=
// Access: Published
// Description:
//////////////////////////////////////////////////////////////
bool NetAddress::
operator != (const NetAddress &other) const {
return _addr != other._addr;
}

View File

@ -46,6 +46,10 @@ PUBLISHED:
void output(ostream &out) const;
size_t get_hash() const;
bool operator == (const NetAddress &other) const;
bool operator != (const NetAddress &other) const;
private:
Socket_Address _addr;
};