Classic Network API
Overview
The classic network API establishes the basis for more complex classes like protocol implementations.
(HTTP, SMTP, POP, ...) or class libraries like the Multiplayer Framework.
This page describes the usage of the core classes for network development.

About Internet addresses
Every host on the Internet has an address, which is unique on the whole network. Such an IP address is represented by the class EM_INET_ADDRESS. You can create an Internet address for the local host using make_local and for remote hosts with make_by_hostname, which will automatically resolve the host using an external DNS. For better performance, especially if you create a lot of Internet addresses, you should consider to use the creation procedures make_by_ip or make_by_ip_string, which will not query any naming service. This is particularly important on Linux based system, because tests have shown that they do not necessarily cache previous DNS queries, resulting in a very poor performance. Should you later need the hostname nevertheless, you’ve the option to retrieve it using reverse_resolve_blocking.
As you’ve seen, EM_INET_ADDRESS represents an entire host on a network, where as EM_INET_SOCKET_ADDRESS specifies a single socket on a host. In other words, an Internet socket address is just an Internet address with an additional port.
You’ve the possibility to create an EM_INET_SOCKET_ADDRESS out of an existing EM_INET_ADDRESS. In this case you’ll use make_by_inet_address_port. On the other hand, you can also create a fresh socket address. The creation procedures for the later method are very similar to the ones you’ve seen before, except that there is always an additional port number you need to pass as argument.
Internet and socket addresses are used throughout the entire Network API. They provide a generic way to address hosts or specific sockets in a network.
TCP - Transmission Control Protocol
If you need to transmit data over a reliable channel, you can use EiffelMedia's built-in
TCP support.
For the server side, you need to take a look at EM_TCP_SERVER_SOCKET. To create a server that listens on a specific port, you call open after you’ve set a port with set_port. Incoming connection attempts will then fire an event to all subscribers of the connection_accepted_event. The event will pass an instance of EM_TCP_CLIENT_SOCKET as argument, which is then used to transmit the actual data.
To establish a connection to a server, you’ll also use an
EM_TCP_CLIENT_SOCKET. After having set the remote address using the creation procedure
make_from_address or some of the
setters, you can connect to the remote side by calling
connect.
The following events are available for subscription:
- connection_established_event: Fired if the connection to the remote host has been established.
- connection_closed_event: Fired if the connection has been closed by the remote host.
- connection_failed_event: Fired if the connection could not be established in time.
- data_received_event: Fired if new data arrived. The argument contains the data as STRING.
Sending data is very easy, just call send_string. Close the connection by calling disconnect.
How do I...
- accept incoming TCP connections on port 1234?
- Create an instance of EM_TCP_SERVER_SOCKET.
- Call set_port (1234) on it.
- Subscribe an agent to accept connection attempts by connection_accepted_event. subscribe (agent my_connection_handler (?)).
- Open the socket for listening by calling open.
- All incoming connection attempts will call the agent you've subscribed. An instance of EM_TCP_CLIENT_SOCKET is passed as argument, which you can use to transmit data to and from the new client. You may want to subscribe to additional events of the client socket.
- connect to a remote host with TCP?
- Create an instance of EM_INET_SOCKET_ADDRESS that represents the host you want to connect to.
- Create an instance of EM_TCP_CLIENT_SOCKET and pass the socket address as argument to make_from_address.
- Subscribe an agent to handle incoming data by data_received_event. subscribe (agent my_data_receiver (?)). The data is passed as argument to the agent.
- Optionally subscribe to the events connection_established_event, connection_failed_event, connection_closed_event in the same way.
- Call connect.
- If the connection could be established, is_connected will be set to True. You can then use send_string to send data to the remote host.
UDP - User Datagram Protocol
UDP support in EiffelMedia is provided by the
three classes EM_SIMPLE_UDP_SOCKET,
EM_UDP_SOCKET and
EM_UDP_PACKET.
All data that is being sent or received by UDP is encapsulated in an EM_UDP_PACKET. Every packet has an address, which can either be its source address or its destination address, depending on the usage of the packet. You can change this address using set_address. The actual data is available in item and can bet set with put_string. To send or receive a packet, you’ll need an EM_SIMPLE_UDP_SOCKET. open starts listening on all local interfaces on a specific port.
Afterwards you can test for a new incoming packet by is_packet_ready and receive it using receive_packet. The packet is then made available in last_packet. Sending is even easier: Prepare your packet (set its address and data) and pass it as argument to send. The socket doesn’t even need to be opened.
As you might have noticed, it is necessary to poll a socket for ready packets. This can be unhandy for some types of applications. EM_UDP_SOCKET is the preferred alternative to the classic socket, which uses events instead of polling. The handling is similar to the EM_SIMPLE_UDP_SOCKET, but you have the possibility to send data directly without creating a packet first using send_direct.
The following events are available for subscription:
- data_received_event: Fired if a new packet arrived. The packet is passed as argument.
- send_failed_event: Fired if data sending was not successful. The errorcode is passed as argument. This can either be Em_error_resolve_ip or Em_error_send_failed.
How do I...
- send data by UDP?
- Create an instance of EM_INET_SOCKET_ADDRESS that represents the destination of the data you want to send.
- Create an instance of EM_UDP_SOCKET.
- Pass the data and the socket address to send_direct. An EM_UDP_PACKET will automatically be created for you!
- receive data by UDP on a specific port?
- Create an instance of EM_UDP_SOCKET.
- Use set_port to set the listening port.
- Subscribe an agent to the data_received_event, which will pass an EM_UDP_PACKET as argument that contains the incoming data.
- Call open, to start listening for data.
HTTP - Hyper Text Transfer Protocol
Extended HTTP 1.0 support is available trough the class
EM_HTTP_PROTOCOL. Extended means, that
connections to virtual hosts are possible. The protocol supports HTTP GET and POST requests through the
features get and
post. The interface is very
simliar to EM_TCP_CLIENT_SOCKET,
except of the following differences:
- Besides of a host, you must set a path by set_path. This path referrs to the location you want to receive. If you want to receive the root of a host, you must set '/' as path.
- The data_received_event only contains the data of the HTTP body. If you need access to the HTTP header, you need to subscribe to header_received_event too.
How do I...
- receive the HTML source of http://se.inf.ethz.ch/projects/index.html
?
- Create an instance of EM_HTTP_PROTOCOL.
- Call set_host ("http://se.inf.ethz.ch").
- Call set_path ("/projects/index.html") on it.
- Subscribe an agent to receive data by calling data_received_event. subscribe (agent my_data_handler (?)).
- Send the HTTP request using initiate_transfer.
- make a POST request and attach a message body?
Similar to the question above, but you use post instead of get, supplying POST data as argument.
Examples
There are several examples provided:
- echo_server: A simple TCP and UDP echo server. Have a look at this examples if you want to build a server.
-
message_client: A nice message client which can send TCP and UDP messages to an arbitrary host.
Hint: Use the echo_server in combination with the message_client: The echo server will bounce all messages back to the client. This is really handy for testing purposes!
- For simple non-event-based tasks take a look at the classic_udp example using EM_SIMPLE_UDP_SOCKET.
- Other examples using UDP are located in the multiplayer section.
