Skip Navigation Links | |
Exit Print View | |
ONC+ Developer's Guide Oracle Solaris 11.1 Information Library |
1. Introduction to ONC+ Technologies
4. Programmer's Interface to RPC
5. Advanced RPC Programming Techniques
6. Porting From TS-RPC to TI-RPC
Differences Between TI-RPC and TS-RPC
Creating and Destroying Services
Registering and Unregistering Services
7. Multithreaded RPC Programming
8. Extensions to the Oracle Solaris RPC Library
The changes in client creation from TS-RPC to TI-RPC are illustrated in Example 6-1 and Example 6-2. Each example:
Creates a UDP descriptor
Contacts the remote host's RPC binding process to get the service's address
Binds the remote service's address to the descriptor
Creates the client handle and set its timeout
Example 6-1 Client Creation in TS-RPC
struct hostent *h; struct sockaddr_in sin; int sock = RPC_ANYSOCK; u_short port; struct timeval wait; if ((h = gethostbyname( "host" )) == (struct hostent *) NULL) { syslog(LOG_ERR, "gethostbyname failed"); exit(1); } sin.sin_addr.s_addr = *(u_int *) hp->h_addr; if ((port = pmap_getport(&sin, PROGRAM, VERSION, "udp")) == 0) { syslog (LOG_ERR, "pmap_getport failed"); exit(1); } else sin.sin_port = htons(port); wait.tv_sec = 25; wait.tv_usec = 0; clntudp_create(&sin, PROGRAM, VERSION, wait, &sock);
The TI-RPC version of client creation, shown in the following example, assumes that the UDP transport has the netid udp. A netid is not necessarily a well-known name.
Example 6-2 Client Creation in TI-RPC
struct netconfig *nconf; struct netconfig *getnetconfigent(); struct t_bind *tbind; struct timeval wait; nconf = getnetconfigent("udp"); if (nconf == (struct netconfig *) NULL) { syslog(LOG_ERR, "getnetconfigent for udp failed"); exit(1); } fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL); if (fd == -1) { syslog(LOG_ERR, "t_open failed"); exit(1); } tbind = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR); if (tbind == (struct t_bind *) NULL) { syslog(LOG_ERR, "t_bind failed"); exit(1); } if (rpcb_getaddr( PROGRAM, VERSION, nconf, &tbind->addr, "host") == FALSE) { syslog(LOG_ERR, "rpcb_getaddr failed"); exit(1); } cl = clnt_tli_create(fd, nconf, &tbind->addr, PROGRAM, VERSION, 0, 0); (void) t_free((char *) tbind, T_BIND); if (cl == (CLIENT *) NULL) { syslog(LOG_ERR, "clnt_tli_create failed"); exit(1); } wait.tv_sec = 25; wait.tv_usec = 0; clnt_control(cl, CLSET_TIMEOUT, (char *) &wait);
Example 6-3 and Example 6-4 show the differences between broadcast in TS-RPC and TI-RPC. The older clnt_broadcast() is similar to the newer rpc_broadcast(). The primary difference is in the collectnames() function: it deletes duplicate addresses and displays the names of hosts that reply to the broadcast.
Example 6-3 Broadcast in TS-RPC
statstime sw; extern int collectnames(); clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &sw, collectnames); ... collectnames(resultsp, raddrp) char *resultsp; struct sockaddr_in *raddrp; { u_int addr; struct entry *entryp, *lim; struct hostent *hp; extern int curentry; /* weed out duplicates */ addr = raddrp->sin_addr.s_addr; lim = entry + curentry; for (entryp = entry; entryp < lim; entryp++) if (addr == entryp->addr) return (0); ... /* print the host's name (if possible) or address */ hp = gethostbyaddr(&raddrp->sin_addr.s_addr, sizeof(u_int), AF_INET); if( hp == (struct hostent *) NULL) printf("0x%x", addr); else printf("%s", hp->h_name); }
The following code example shows broadcast in TI-RPC.
Example 6-4 Broadcast in TI-RPC
statstime sw; extern int collectnames(); rpc_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &sw, collectnames, (char *) 0); ... collectnames(resultsp, taddr, nconf) char *resultsp; struct t_bind *taddr; struct netconfig *nconf; { struct entry *entryp, *lim; struct nd_hostservlist *hs; extern int curentry; extern int netbufeq(); /* weed out duplicates */ lim = entry + curentry; for (entryp = entry; entryp < lim; entryp++) if (netbufeq( &taddr->addr, entryp->addr)) return (0); ... /* print the host's name (if possible) or address */ if (netdir_getbyaddr( nconf, &hs, &taddr->addr ) == ND_OK) printf("%s", hs->h_hostservs->h_host); else { char *uaddr = taddr2uaddr(nconf, &taddr->addr); if (uaddr) { printf("%s\n", uaddr); (void) free(uaddr); } else printf("unknown"); } } netbufeq(a, b) struct netbuf *a, *b; { return(a->len == b->len && !memcmp( a->buf, b->buf, a->len)); }