Basic usage of Ecore_Con_Server

Table of Contents

Start a server

We create a Ecore_Con_Server object with the ecore_con_server_add. This function takes a connection type parameter that defines the type of the connection that will be created with the client. This type can be composed of several of the follwing values:

  • ECORE_CON_LOCAL_USER: local user socket in “~/.ecore”;
  • ECORE_CON_LOCAL_SYSTEM: local system socket in “/tmp”;
  • ECORE_CON_LOCAL_ABSTRACT: abstract socket;
  • ECORE_CON_REMOTE_TCP: remote TCP server;
  • ECORE_CON_REMOTE_UDP: remote UDP server;
  • ECORE_CON_REMOTE_MCAST: remote multicast server;
  • ECORE_CON_REMOTE_BROADCAST: remote broadcast server;
  • ECORE_CON_REMOTE_NODELAY: remote connection sending data immediately without buffering;
  • ECORE_CON_REMOTE_CORK: remote connection sending large chunks of data;
  • ECORE_CON_USE_SSL3: enable SSL3;
  • ECORE_CON_USE_TLS: enable TLS;
  • ECORE_CON_USE_MIXED: enable both SSL3 and TLS;
  • ECORE_CON_LOAD_CERT: use a loaded certificate;
  • ECORE_CON_NO_PROXY: disable proxy on the server.
To compose a type with more than one value, add a '|' between them.

Here we will create a remote TCP server on the local host (127.0.0.1) that will be listening on the port 8080.

Ecore_Con_Server *svr;
svr = ecore_con_server_add(ECORE_CON_REMOTE_TCP, "127.0.0.1", 8080, NULL));
The ecore_con_server_add() function can return NULL if it cannot create the server.

Configure the server

We will set a maximum number of simultaneous connections to our server in order to prevent it from being overloaded. As an example we will limit the connections to three clients: if three clients are connected, a new oncoming client will have to wait until one of the connected clients disconnects before being able to actually connect to the server.

ecore_con_server_client_limit_set(svr, 3, 0);

The last parameter of this function determines how the excess clients will be rejected. If set to 1, the client that tries to connect will be disconnected if there are already too many of them connected, whereas setting to 0 will have the client wait until another client disconnects.

To avoid a client holding a connection for too long, we can set a timeout after which an inactive client will be disconnected. In the following example, we set a ten seconds timeout.

ecore_con_server_timeout_set(svr, 10);

Register callbacks on events

We need to register callbacks on events to be able to know when clients connect to the server or send data. We can register callbacks on the following events:

  • ECORE_CON_EVENT_CLIENT_ADD: a client connects to the server;
  • ECORE_CON_EVENT_CLIENT_DEL: a client disconnects;
  • ECORE_CON_EVENT_CLIENT_ERROR: an error occurred while trying to reach the client;
  • ECORE_CON_EVENT_CLIENT_DATA: a connected client has sent data.

Here we only register callbacks on add, del and data events. The _add_cb() callback prints the IP address and port of the client that just connected, and also whether it is still connected. It then returns ECORE_CALLBACK_RENEW to keep the callback handler on the ECORE_CON_EVENT_CLIENT_ADD event.

The _del_cb() callback prints the IP address and the uptime of the client that disconnects. It then calls ecore_con_client_del() to close the connection and free the memory allocated to the client.

Finally the _data_cb() callback prints the size of the data received by the client.

Callbacks definition__: <code c> static Eina_Bool _add_cb(void *data UNUSED__, int type UNUSED__, Ecore_Con_Event_Client_Add *ev) { printf(“Client connection: ip %s, port %d, connected = %d!\n”, ecore_con_client_ip_get(ev->client), ecore_con_client_port_get(ev->client), ecore_con_client_connected_get(ev->client)); return ECORE_CALLBACK_RENEW; } static Eina_Bool _del_cb(void *data UNUSED__, int type UNUSED__, Ecore_Con_Event_Client_Del *ev) { printf(“Client disconnected: ip %s uptime %0.3f seconds\n”, ecore_con_client_ip_get(ev->client), ecore_con_client_uptime_get(ev->client)); Close the connection with the client ecore_con_client_del(ev->client); return ECORE_CALLBACK_RENEW; } static Eina_Bool _data_cb(void *data UNUSED__, int type UNUSED__, Ecore_Con_Event_Client_Data *ev) { printf(“Received data from client: ip %s port %d size %i bytes\n”, ecore_con_client_ip_get(ev->client), ecore_con_client_port_get(ev->client,ev->size); ev->data contains the data sent by the client printf(“%s\n”,ev->data); return ECORE_CALLBACK_RENEW; } </code> Here are the callback registrations: <code c> ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb)_add_cb, NULL); ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb)_del_cb, NULL); ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb)_data_cb, NULL); </code> ==== Sending data to the client ==== Once connected, we can send data to the client. <code c> char hello[] = “hello Client ! I am the server.”; ecore_con_client_send(ev->client, hello, sizeof(hello)); ecore_con_client_flush(ev->client); </code> The ecore_con_client_send() function is used to send the data, and the ecore_con_client_flush() function is to avoid buffering and sending this data to the client immediately.

——-