Server and client transports are responsible for the actual transmission and reception of network messages. A
RcfServer contains one or more server transports, while a client contains only a single client transport.
To access the server transports of a
RcfServer, capture the return value of
Alternatively, if the
RcfServer only has a single server transport, you can access it by calling
On the client side, the client transport is availablable through
For server-side transports, it is generally necessary to set an upper limit on the size of incoming network messages. Without an upper limit, it is possible for malformed requests to cause arbitrarily sized memory allocations on the server.
The maximum incoming message length setting of a RCF server transport defaults to 1 Mb, and can be changed by calling
Similarly, there is a maximum incoming message length setting for client transports. It defaults to 1 Mb and can be changed by calling
As client transports only receive network messages from a peer they have connected to, the risk of malformed packets is not as great as for server transports.
It is possible to query a
RcfClient<> for the sizes of the latest request and response messages sent:
To set the maximum number of simultaneous connections to a RCF server transport:
This setting is not relevant to the UDP server transport, as there is no concept of connections within the UDP protocol.
For IP-based server transports, you can allow the local system to assign a server port number automatically, by specifying 0 as the port number. When the server starts, the system will find a free port and assign it to the server. The port number can subseqently be retrieved through
For IP-based server transports, client access can be allowed or denied, based on the IP addresses of the clients.
To configure IP rules for allowing clients, use RCF::IpServerTransport::setAllowIps():
To configure IP rules for denying clients, use RCF::IpServerTransport::setDenyIps():
RCF supports both IPv4 and IPv6. IPv6 support is enabled by default in RCF, but you can define
RCF_FEATURE_IPV6=0 to disable it (see Building RCF).
For example, to run a server and client over a loopback IPv4 connection:
To run a server and client over a loopback IPv6 connection instead, specify
::1 instead of
RCF uses the POSIX
getaddrinfo() function to resolve IP addresses.
getaddrinfo() can return either IPv4 or IPv6 addresses, depending on the configuration of the local system and network. So the following client will use either IPv4 or IPv6, depending on how the local system and network have been configured:
On machines with dual IPv4/IPv6 stacks, you will probably want your server to listen on both IPv4 and IPv6 addresses. To do this portably, you should listen on both
On some platforms, it is sufficient to listen only on
::0, as the system will translate incoming IPv4 connections into IPv6 connections with a special class of IPv6 addresses.
RcfClient<> connects to a server using an IP-based transport, the default behavior is to allow the system to decide which local network interface and local port to use. In some circumstances, you may want to explicitly set the local network interface a client should bind to.
You can do so by calling
RCF::IpClientTransport::setLocalIp(), before connecting:
RcfClient<> has connected, you can determine which local network interface and port it is bound to, by calling
RCF provides access to the underlying OS primitives, such as sockets and handles, of client and server transports. For example:
This can be useful if you need to set custom socket options.
This sections covers the various transport types that are implemented in RCF.
TCP endpoints are represented in RCF by the
RCF::TcpEndpoint class, constructed from an IP address and a port number.
Server transports interpret the IP address as the local network interface to listen on. So for example
"0.0.0.0" should be specified in order to listen on all available IPv4 network interfaces, and
"127.0.0.1" should be specified to listen only on the loopback IPv4 interface. If no IP address is specified,
"127.0.0.1" is assumed.
RCF::UdpEndpoint also contains some extra functionality, to deal with multicasting and broadcasting.
RCF::UdpEndpoint can be configured to listen on a multicast IP address:
Note that the server still needs to specify a local network interface to listen on.
To send multicast messages, specify a multicast IP address and port when creating the client:
To send broadcast messages, specify a broadcast IP address and port:
RCF's UDP server transport can be configured to share its address binding, so that multiple
RcfServer's can listen on the same port of the same interface. This is enabled by default when listening on multicast addresses, but can also be enabled when listening on non-multicast addresses. This can be useful if multiple processes on the same machine need to listen to the same broadcasts:
In situations where servers are started on dynamically assigned ports, multicasting and broadcasting can be a useful means of communicating server IP addresses and ports to clients. For example:
Note that here we are actually using a multicast address to broadcast information to clients. If multicasting had been unavailable on this particular network, we could also have used an IP broadcast address instead of an IP multicast address.
RCF supports Win32 named pipe transports.
RCF::Win32NamedPipeEndpoint takes one constructor parameter, which is the name of the named pipe, with or without the leading
An advantage of using Win32 named pipes, is that they allow easy authentication of clients. A server using a Win32 named pipe server transport can authenticate its clients through the
RCF::Win32NamedPipeImpersonator class, which uses the Windows API function
ImpersonateNamedPipeClient() to impersonate the client:
If we had used a TCP connection to
127.0.0.1 instead, we would have needed to enable Kerberos or NTLM authentication to securely determine the clients user name (see Transport protocols).
UNIX domain sockets function analogously to Win32 named pipes, and allow efficient communication between servers and clients on the same machine.
RCF::UnixLocalEndpoint takes one parameter, which is the name of the UNIX domain socket. The name must be a valid filesystem path. For servers, the program must have sufficient privilege to create the given path, and the file must not already exist. For clients, the program must have sufficient privilege to access the given path.
Here is a simple example:
HTTPS is essentially the HTTP protocol layered on top of the SSL protocol. As such, configuration of the SSL aspects of HTTPS, is done in the same way as for the SSL transport protocol (see Transport protocols).
To setup a server with an HTTP endpoint, use
Similarly, for an HTTPS endpoint, use
Client side configuration is similar, using
RCF::HttpEndpoint for a HTTP client:
RCF::HttpsEndpoint for a HTTPS client: