next up previous contents
Next: A. Internal Server-Side Up: CFHT Socket I/O Previous: 2. Server-Side   Contents

3. Client-Side

Just as the server side calls are used to build a server, this part of libsockio can be used to build a protocol library for your server. The API for envserv, called libssenv is an example. That, in turn is used by the ssGetenv and ssSetenv client programs which talk to envserv. (Refer to figure 2 to see how the pieces depend on each other.) The source files sockclnt.h and sockclnt.c contain calls which can be used to build an API library like libssenv.


3.1 sockclnt_t* sockclnt_create(const char* hostspec, int io_timeout_seconds)

This returns a pointer to a sockclnt_t that must be passed back to the other functions below. A connection attempt is made immediately. Each host in hostspec (see below) is tried at most one time by this call. Any subsequent calls to other sockclnt routines will (indefinitely) keep trying to re-establish the connection by cycling through the list (unless you define a disconnect_hook() and exit the program.)

The hostspec argument must be a string of the form "hostname:port,hostname2:port,...". The hostname can be either an IP address or resolvable host name, and port can be either a port number or resolvable service name. If the first hostname:port specification fails, sockclnt_create() and any later attempts to reconnect will cycle through all of the choices.

The timeout for a connection, a read (sockclnt_recv), and a write (sockclnt_send) is set in the io_timeout_seconds parameter. 15 seconds is a reasonable value, but the correct setting depends on your protocol and function of the server.

3.2 disconnect_hook(void* userdata)

3.3 reconnect_hook(void* userdata)

If this happens, a reconnect_hook function in the user code will be called after the connection is back up. This function may exchange messages with the server to rebuild any state information that was lost when the old connection broke. If reconnect_hook is not needed, do not set it.

3.4 void sockclnt_destroy(sockclnt_t* sc)

This closes the underlying file descriptor and frees resources allocated by sockclnt_create().

3.5 void sockclnt_send(sockclnt_t* sc, const char* message)

Reconnects and/or sends a message to the server. If a previous receive operation has failed, sockclnt_send will reconnect to the server. If such a reconnection was needed, and if a user reconnect_hook has been defined, it will be called before the message is sent so it has the chance to renegotiate the current state with the server. reconnect_hook will also be called if ``message'' can not be sent completely. This function will try to reconnect to the server and send the message indefinitely. The only way to give up is to implement a reconnect_hook that raises a signal, exits, or never returns. A warning message will be printed to stderr when a retry is in progress.

By passing NULL for ``message'', this function can be used to ensure a connection to the status server. For example, socket clients which use sockclnt_check or sockclnt_recv will want to use sockclnt_send(sc, NULL) any time a NULL is returned from these functions. Instead of passing a NULL, it may be necessary to resend the most recent protocol command.

If ``message'' is not NULL, the design of the server-side of sockio, requires that it be followed by one or more calls to receive a response. This is because the server must generate a response to all messages that it receives (except for disconnect, but even in that case the receive function should be called to get the end-of-file.)

3.6 const char* sockclnt_recv(sockclnt_t* sc)

This waits up to io_timeout_seconds (or indefinitely if timeout is 0) for a response to the previously sent message. If the ``response'' is end-of-file or a timeout happens, then NULL is returned when the server closes the socket. A NULL is also returned in case of any error. In any of the cases that NULL is returned, a subsequent call to sockclnt_send will cause the connection to be re-established. This receive call never handles reconnecting though. (It wouldn't make sense, because if the socket closed unexpectedly while reading a response, the request will have to be re-sent anyway, and the client code must handle that.)

3.7 const char* sockclnt_check(sockclnt_t* sc)

Like sockclnt_recv, but returns NULL immediately if no messages are waiting.

next up previous contents
Next: A. Internal Server-Side Up: CFHT Socket I/O Previous: 2. Server-Side   Contents
Sidik Isani