PTypes: networking: ipmessage

Top: Networking: ipmessage

>     #include <pinet.h>

>     class ipmessage {
>         ipmessage();
>         ipmessage(ipaddress ip, int port);
>         ipmessage(string host, int port);

>         bool   waitfor(int timeout);
>         void   send(const char* buf, int count);
>         void   send(string s);
>         int    receive(char* buf, int count [, ipaddress& src ] );
>         string receive(int max [, ipaddress& src ] );

>         ipaddress get/set_ip();
>         string    get/set_host();
>         int       get/set_port();
>         ipaddress get_myip();
>         int       get_myport();

>         virtual void sockopt(int socket);
>     }

The ipmessage class implements connectionless, unreliable datagram communication between IP hosts. The underlying protocol (UDP) never guarantees that a message will be delivered, however, in return, it has the ability to send broadcast messages on a local network. Unlike stream-oriented protocols which have some traffic overhead because of the control packets (for opening/closing connections and for confirming each delivery), message-oriented protocols always send a single packet, sometimes fragmented if it exceeds the size of a physical frame.

In summary, message-oriented communication is useful in the following situations:

- For sending streaming data (as a rule, sound or video) when losing packets is not crucial. An application may measure the bandwidth and the reliability of a connection before starting a streaming session, to estimate the optimal frequency of packets and adjust the quality of multimedia data (e.g. frames per second, resolution, etc).
- For finding hosts of a specific type on a local network using broadcast/multicast messages. You may want your client application to find its services on a network automatically to free the user from entering the addresses manually.
- For sending very short messages or request/reply cycles, possibly with confirmation/retry mechanism. In most cases developing such applications may be costly compared to using stream-oriented protocols instead.

The maximum message size is limited to 64 KBytes on most systems. Note however, that sending large messages may result in fragmentation and hence a lesser probability that the whole message will be delivered. You may assume that a maximum data size for a UDP message is 1472 bytes, even though such message may still be fragmented when transferred over a non-Ethernet medium. The size of a guaranteed indivisible UDP packet is 512 bytes on all physical media types.

For larger data chunks you may consider using streaming protocols, since the TCP control traffic overhead is insignificant compared to data in such cases.

The ipmessage and ipmsgserver classes are not compatible with PTypes streaming interfaces due to unreliable and connectionless nature of the underlying protocol. These classes provide a pair of low-level methods receive() and send() and require that the client (ipmessage) first call send() prior to receiving, and the server (ipmsgserver) must first receive data prior to sending. In addition, the server object can be polled for pending data (optionally with timed waiting) using poll().

The ipmessage class is reusable, i.e. you may use one object to send data to multiple destinations by changing the ip (or host) and port properties.

Ipmessage can generate exceptions of type (estream*) with a corresponding error code and a message string.

(See also Example 3 in Examples)

ipmessage::ipmessage() is the default constructor.

ipmessage::ipmessage(ipaddress ip, int port) constructs an ipmessage object and assigns the peer ip/port values. To send a broadcast message to all hosts on a local network, assign a predefined constant ipbcast to ip.

ipmessage::ipmessage(string host, int port) constructs an ipmessage object and assigns the peer host name and port values. Before actually sending data first time, the object resolves the host name to a numeric IP address. Host can be either a symbolic DNS name or a numeric address in a string form (e.g. "somehost.com" or "192.168.1.1").

bool ipmessage::waitfor(int milliseconds) waits on a socket until data is available for reading (returns true) or the time specified has elapsed, in which case it returns false.

ipmessage::send(const char* buf, int count) sends data to the peer. Ip/host and port properties must be assigned prior to calling send(). A client must first call send() before receiving data from the peer.

ipmessage::send(string s) works like the previous version of send() except that it sends the string s (not including the terminating null-symbol).

int ipmessage::receive(char* buf, int count [, ipaddress& src ] ) reads data from the socket. Receive() may hang if no data is available for reading. This function returns the actual number of bytes read. If the packet received exceeds the size of the supplied buffer, an exception is raised with code EMSGSIZE. You may check if there is data available for reading without 'hanging' using waitfor() described above. The last optional parameter src receives the IP address of the host that sent this packet: it may be useful if the packet is received in response to a broadcast request.

string ipmessage::receive(int max [, ipaddress& src ] ) works like the previous version of receive() except that it returns data in a dynamic string. The parameter max specifies the limit which may not be exceeded when reading data from the network, like with the previous version of receive().

ipaddress ipmessage::get/set_ip() sets/retrieves the peer address in a numerical form. If the object was constructed using a symbolic name, get_ip() may perform a DNS lookup (only once). To send a broadcast message to all hosts on a local network, assign a predefined constant ipbcast to this property.

string ipmessage::get/set_host() sets/retrieves the peer address in a symbolic form. If the object was constructed using a numeric IP address, get_host() may perform a reverse DNS lookup.

int ipmessage::get/set_port() sets/retrieves the peer port number.

ipaddress ipmessage::get_myip() returns the local address associated with the socket.

int ipmessage::get_myport() returns the local port number associated with the socket.

virtual void ipmessage::sockopt(int socket) - override this method in a descendant class if you want to set up additional socket options (normally, by calling setsockopt()).

See also: ipmsgserver, Utilities, Examples

PTypes home