file name: sockinet.hpp, sockinet.cpp
classification: simulation
contents: class CInternetAddress
derived from: class ACSocketAddress
use: provides a internet domain socket address
global items used:
The following items are only needed in pSOS. Since the network management module (pNA) does not keep a table for the mapping of host names to their network addresses, the function gethostbyname() and the struct hostent returned by it have to be provided. See below for implementation details.
struct hostent:
The structure just contains a void *h_addr pointer and an INT8
h_length field specifying the size of the address pointed to by h_addr.
If h_addr does not point to a valid address, it is NULL.
struct hostent
*gethostbyname (const char *host): The function has access to an internal
table of known hosts and their network addresses, and it keeps a static(!)
variable of type hostent. It searches the host in the
table of host names, and if it finds the name, it sets the h_addr
pointer of this static variable to the corresponding IP address. The h_length
field is set to 4. Then, a pointer to the static variable is returned.
If the host name was not found, the function returns NULL.
Note: since the variable that is returned is static, you should
copy its contents at once if you need them any further. In any case, the
function is not reentrant, and a second call to it will overwrite whatever
the first call returned.
member variables:
sockaddr_in*
addr_: pointer to the internet address structure.
member functions:
CInternetAddress():
This constructor is for servers: it creates a new object of type sockaddr_in
(internet domain address structure), sets the family to AF_INET, the socket
address to INADDR_ANY (that allows the server to receive from all addresses)
and the port to 0 (that means that the port will be assigned).
CInternetAddress
(int port): This constructor is also for servers: it creates a new
object of type sockaddr_in (internet domain address structure),
sets the family to AF_INET, the socket address to INADDR_ANY (that allows
the server to receive from all addresses) and the port to port.
CInternetAddress
(const char* host, int port): The constructor should be used for clients:
it creates a new object of type sockaddr_in, sets the family to
AF_INET, gets the host address calling gethostbyname(), and finds
out the network port using htons().
CInternetAddress
(unsigned long ipaddress, int port): This constructor should also
be used for clients: it creates a new object of type sockaddr_in,
sets the family to AF_INET, the address to ipaddress converted
by htonl(), and the network port to port converted by
htons().
CInternetAddress
(const CInternetAddress &inet): Creates a new object of type sockaddr_in
and copies the complete sockaddr_in structure from inet
(using memcpy()).
virtual
~CInternetAddress(): Deletes the address structure.
virtual
sockaddr* Addr() const: returns a pointer to the address structure
itself, which is cast to the base address structure sockaddr.
virtual
int Family() const: should always return AF_INET.
virtual
int Size() const: returns the size of the address structure.
implementation details of gethostbyname() in pSOS:
This section is only valid if the operating system used is pSOS, that is, if PSOS_SIM is defined. As already explained, pSOS does not keep a table for mapping host names to IP addresses. Therefore, sockinet.cpp contains two local tables, one for the host names, and another one with the addresses of the hosts. Unfortunately, the Microtec compiler does not handle static initialization correctly (it does not complain if the arrays are initialized statically, but it just sets all entries to 0; the same code, compiled with the GNU compiler, did initialize the arrays, so it appears to be a bug in the Microtec compiler). Therefore, the arrays have to be initialized manually. This is done by a static local object whose sole task it is to initialize the arrays in its constructor. The advantage of this approach is that the object updates both tables at once, so it is less error prone than static initialization.
const int
NumberOfHosts: This constant determines the number of entries that
are preallocated in the table. It gives the maximum number of host names
(and corresponding addresses) that can be stored.
char *hosts[NumberOfHosts]:
The table contains all known host names. Note that there is no automatic
expansion of addresses. If a host hast the name hugo.company.com,
and if you also want to specify that host as hugo, you have to
make entries for both. The first unused array entry is set to NULL.
INT32 haddress[NumberOfHosts]:
The table contains the IP addresses of the hosts. If a host name is found
in the hosts table, than its IP address is taken from the same
index in the haddress table. Therefore, it is vital that the two
tables correspond.
struct SHostent:
This structure is derived from struct hostent and provides constructors
for initializing the members of hostent. Both constructors set
h_length to 4, but whereas the default ctor sets h_addr
to NULL, the second ctor SHostEnt (INT32 *address) sets h_addr
to address. A function void Set (INT32 *address) is used
to set h_addr to address at some later time.
struct SHostManager:
The structure is needed to initialize the host and address tables during
program startup. It consists of a default constructor, a Set()
function for adding a new host and address pair to the tables, a destructor
for deleting the memory allocated for the host names, and a private member
index_ which contains the first free index in the tables.
The constructor SHostManager() first sets index_
to zero, and then calls Set() for each host that should be added
to the tables. If you want to add some more hosts, then you have to put
additional calls to Set() in the ctor. The last statement of the
ctor sets the first free entry in the hosts table to NULL (only
if index_ is less then NumberOfHosts).
void Set (const char *hostname, INT32 address) first asserts
that there is still an unused entry left in the tables, and that hostname
is not NULL. If both conditions are true, the hostname is copied
into the first free entry in the hosts table (memory is allocated
to contain it), the address is stored in the haddress
table, and index_ is incremented.
The destructor ~SHostManager() iterates through the hosts
table and frees the memory allocated for the host names.
SHostManager
hostManager_: This variable is never used. However, defining it causes
its constructor to be called during the initialization phase of the program,
so the tables are already initialized when main() is executed.
struct hostent
*gethostbyname (const char *host): The function iterates through the
hosts table and compares the host parameter to the host
names stored in the table. If it finds the name, then it sets the h_addr
pointer of a static variable of type hostent to the corresponding
IP address and returns a pointer to the static hostent variable.
If the host is not stored in the hosts table, NULL is
returned.
If host is NULL, an assert fails.