The client.c file in the one-way messaging example is modified in this section to demonstrate how to use the non-blocking I/O mode. In this new file, client_nonblo.c, the I/O mode is specified as non-blocking with the RPC_CL_NONBLOCKING argument, the flush mode is chosen to be blocking by use of the RPC_CL_BLOCKING_FLUSH. The I/O mode and flush mode are invoked with CLSET_IO_MODE. When an error occurs RPC_CANT_STORE is returned to the client and the program tries to flush the buffer. To choose a different method of flush consult the clnt_control(3NSL) man page.
#include <stdio.h>
#include "counter.h"
main(int argc, char *argv[])
{
CLIENT* clnt;
enum clnt_stat result;
char *server;
int number;
bool_t bres;
/*
* Choose the I/O mode and flush method to be used.
* The non-blocking I/O mode and blocking flush are
* chosen in this example.
*/
int mode = RPC_CL_NONBLOCKING;
int flushMode = RPC_CL_BLOCKING_FLUSH;
if (argc != 3) {
fprintf(stderr, "usage: %s server_name number\n", argv[0]);
exit(1);
}
server = argv[1];
number = atoi(argv[2]);
clnt= clnt_create(server, COUNTERPROG, COUNTERVERS, "tcp");
if (clnt == (CLIENT*) NULL) {
clnt_pcreateerror(server);
exit(1);
}
/*
* Use clnt_control to set the I/O mode.
* The non-blocking I/O mode is
* chosen for this example.
*/
bres = clnt_control(clnt, CLSET_IO_MODE, (char*)&mode);
if (bres)
/*
* Set flush mode to blocking
*/
bres = clnt_control(clnt, CLSET_FLUSH_MODE, (char*)&flushMode);
if (!bres) {
clnt_perror(clnt, "clnt_control");
exit(1);
}
/*
* Call the RPC services.
*/
result = add_1(number, clnt);
switch (result) {
case RPC_SUCCESS:
fprintf(stdout,"Success\n");
break;
/*
* RPC_CANTSTORE is a new value returned to the
* client when the buffer cannot store a request.
*/
case RPC_CANTSTORE:
fprintf(stdout,"RPC_CANTSTORE error. Flushing ... \n");
/*
* The buffer is flushed using the blocking flush method
*/
bres = clnt_control(clnt, CLFLUSH, NULL);
if (!bres) {
clnt_perror(clnt, "clnt_control");
}
break;
default:
clnt_perror(clnt, "call failed");
break;
}
/* Flush */
bres = clnt_control(clnt, CLFLUSH, NULL);
if (!bres) {
clnt_perror(clnt, "clnt_control");
}
clnt_destroy(clnt);
exit(0);
}