GSK Reference Manual |
---|
Writing a Generic ClientTutorial: Writing a client — How to write a client |
This section of the tutorial describes how to write a client.
The first step in implementing a client is figuring out how to determine the host and port to connect to:
Is there a default host? If not, the host should either be determined programmatically (eg via an environment variable, a configuration file, a command-line parameter, or some other way), or the host may be a standard IP address or name. You may have to wait on DNS lookups; use the gsk_name_resolve function to lookup the name.
The port often defaults to a service-specific default port.
Traditionally /etc/services
gives
a map from the port number to service name.
More often, the default port is just hardcoded into the program.
Let us suppose that you have a server that responds to NUL-terminated requests with NUL-terminated responses. You want to make a client API and a sample client program.
First you have to design the client API:
typedef struct _MyClient MyClient; MyClient *my_client_new (const char *hostname, int port); void my_client_trap_errors (MyClient *client, MyClientErrorFunc func, gpointer data, GDestroyNotify destroy); void my_client_request (MyClient *client, const char *request, MyClientResponseCallback func, gpointer data, GDestroyNotify destroy); void my_client_destroy (MyClient *client);
Then you have to design the MyClient data structure. We will keep a buffer of data that hasn't made it out to the server, and a queue of response callbacks, information about the actual connection, and the error-handlers.
struct _MyClient { GskNameResolverTask *name_lookup; int port; GskStream *connection; GskBuffer outgoing; GskBuffer incoming; GQueue *response_callbacks; MyClientErrorFunc func; gpointer data; GDestroyNotify destroy; };
TODO: Implement it!
Whenever you make an API like that, you should use it in a trivial test program. This is vital for testing and debugging.
In that spirit, we provide a trivial use of the MyClient API.
#include "my-client.h" static void handle_response (const char *response, gpointer data) { g_print ("%s\n", response); gsk_main_quit (); } int main (int argc, char **argv) { gsk_init (&argc, &argv, NULL); if (argc != 4) g_error ("usage: %s HOST PORT QUERY", argv[0]); client = my_client_new (argv[1], atoi (argv[2])); my_client_request (client, argv[3], handle_response, NULL, NULL); return gsk_main_run (); }