Article View: comp.sys.sun
Article #7140Re: RPC server -- How to detect death of client? -- (a tad long)
From: Mike Hoegeman
Date: Fri, 22 Mar 1991 20:20
Date: Fri, 22 Mar 1991 20:20
168 lines
4547 bytes
4547 bytes
In article <1972@brchh104.bnr.ca> anund@idt.unit.no (Anund Lie) writes:
>When running Sun RPC over TCP (or other connection-oriented services, for
>that matter), how can the server detect that a client process has died?
>(More precisely: That no process has the other end of the connection
>open.)
I've seen a couple of questions like this so i'll post below an example of
how I deal with client management in a tcp based RPC service. The comments
explain things fairly well but if anyone has any questions go ahead and
drop me a line
mike hoegeman, mh@awds.imsd.contel.com
------ example below -------
#include <stdio.h>
#include <rpc/rpc.h>
#include "db.h" /* your service.h goes here */
#define LogM fprintf
#define AS_ERROR stderr
#define AS_DEBUG stderr
#define LogInit(X)
#include <sys/errno.h>
extern void db_program_1();
SVCXPRT *transp;
main()
{
LogInit();
(void) pmap_unset(DB_PROGRAM, DB_VERSION);
if (!svc_register(transp,
DB_PROGRAM, DB_VERSION, db_program_1, IPPROTO_UDP))
{
fprintf(stderr, "unable to register (DB_PROGRAM, DB_VERSION, udp).\n");
exit(1);
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL)
{
(void) fprintf(stderr, "cannot create tcp service.\n");
exit(1);
}
if (!svc_register(transp,
DB_PROGRAM, DB_VERSION, db_program_1, IPPROTO_TCP))
{
fprintf(stderr, "unable to register (DB_PROGRAM, DB_VERSION, tcp).\n");
exit(1);
}
run(); /* like svc_run() but does client management callbacks */
(void) fprintf(stderr, "run returned\n");
exit(1);
}
run()
{
extern int errno;
#ifdef FD_SETSIZE
fd_set readfds;
static fd_set oldfds;
oldfds = svc_fdset;
#else
int readfds;
static int oldfds;
oldfds = svc_fds;
#endif /* def FD_SETSIZE */
for (;;)
{
register int setsize;
setsize = _rpc_dtablesize();
#ifdef FD_SETSIZE
readfds = svc_fdset;
#else
readfds = svc_fds;
#endif /* def FD_SETSIZE */
switch (select(setsize, &readfds, (int *) 0, (int *) 0,
(struct timeval *) 0))
{
case -1:
if (errno == EINTR)
continue;
perror("svc_run: - select failed");
return;
case 0:
continue;
default:
{
/*
at the start of each go round in the select loop we can
detect when a new connection has been made or broken this is
were we do our client management
*/
register int chunk;
register int bit;
register unsigned long mask;
register unsigned long *maskp;
int fd;
/* for each bit in the new mask */
maskp = (unsigned long *) (svc_fdset.fds_bits);
for (chunk = 0; chunk < setsize; chunk += NFDBITS)
for (mask = *maskp++;
bit = ffs(mask); mask ^= (1 << (bit - 1)))
{
fd = chunk+bit-1;
/*
if fd is not in the old mask, then we have a
new connection
*/
if (FD_ISSET(fd, &svc_fdset) && !FD_ISSET(fd, &oldfds))
if (c_add(fd))
LogM(AS_ERROR, "add error");
}
/* for each bit in the old mask... */
maskp = (unsigned long *) (oldfds.fds_bits);
for (chunk = 0; chunk < setsize; chunk += NFDBITS)
for (mask = *maskp++;
bit = ffs(mask); mask ^= (1 << (bit - 1)))
{
fd = chunk+bit-1;
/*
if fd is not in the new mask then we have lost
a connection
*/
if (FD_ISSET(fd, &oldfds) && !FD_ISSET(fd, &svc_fdset))
if (c_delete(fd))
LogM(AS_ERROR, "delete error");
}
oldfds = svc_fdset; /* should have a better scheme for
copying fd sets here */
svc_getreqset(&readfds);
}
}
}
}
/* client 'close' callback */
c_delete(n)
int n;
{
LogM(AS_DEBUG,"c_delete: %d <-----\n", n);
return 0;
}
/* client 'open' callback */
c_add(n)
int n;
{
LogM(AS_DEBUG,"c_add: %d <-----\n", n);
return 0;
}
Technical Details
Message-ID:
<2069@brchh104.bnr.ca>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!cunews!bnrgate!brtph3!brchh104!brchs1!bnr.ca!rice.edu!sun-spots-requestShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!cunews!bnrgate!brtph3!brchh104!brchs1!bnr.ca!rice.edu!sun-spots-request From: mh@roger.imsd.contel.com (Mike Hoegeman) Newsgroups: comp.sys.sun Subject: Re: RPC server -- How to detect death of client? -- (a tad long) Keywords: Networks Message-ID: <2069@brchh104.bnr.ca> Date: 22 Mar 91 20:20:20 GMT Sender: news@brchh104.bnr.ca Organization: Sun-Spots Lines: 168 Approved: Sun-Spots@rice.edu X-Original-Date: Wed, 20 Mar 91 20:30:44 GMT X-Refs: Original: v10n57 X-Sun-Spots-Digest: Volume 10, Issue 52, message 9 X-Note: Submissions: sun-spots@rice.edu, Admin: sun-spots-request@rice.edu