|
|
Connectionless-mode transport services, in contrast to connection-oriented services, are message-oriented and support transfer in self-contained units (datagrams) with no necessary logical relationship to each other. Sockets and XTI both provide connectionless-mode service.
All the information required to deliver a datagram (for example, a destination address) is presented to the transport provider, together with the data to be transmitted, in a single service access. A given service access need not relate to any other service access. Each unit of data transmitted is entirely self-contained, and can be independently routed by the transport provider.
The differences between socket library datagrams and the connectionless service provided by XTI parallel the differences between sockets and XTI connection-oriented service described above. The following code sends an Internet domain datagram to a receiver whose host and service names are given as command line arguments.
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #define DATA "It was the best of times. It was the worst of times."The program looks up the host address and the service port (both given on the command line) by calling gethostbyname and getservbyname. The host network address and service port number are in the structures returned by these two library routines. They are copied into the structure that specifies the destination of the message./* * The form of the command line is: * dgramsend hostname servicename */
main(argc, argv) /* send Internet domain datagram */ int argc; char *argv[]; { struct servent *sp, *getservbyname(); int sock; struct sockaddr_in name; struct hostent *hp, *gethostbyname();
/* create socket on which to send */ sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { perror("opening datagram socket"); exit(1); } /* * Find the socket to send to. gethostbyname() returns a structure * including the network address of the specified host. The port * number is taken from the command line. */ hp = gethostbyname(argv[1]); if (hp == 0) { fprintf(stderr, "%s: unknown host\n", argv[1]); exit(2); } memcpy((char *)&name.sin_addr, (char *)hp->h_addr, hp->h_length); name.sin_len = sizeof(name); name.sin_family = AF_INET; sp = getservbyname(argv[2], "tcp"); if (sp == 0) { fprintf(stderr, "%s: unknown service\n", argv[2]); exit(3); } server.sin_port = sp->s_port;
/* send message */ if (sendto(sock, DATA, sizeof(DATA), 0, (struct sockaddr *)&name, sizeof(name)) < 0) perror("sending datagram message"); close(sock); exit(0); }
XTI connectionless service is functionally similar to sockets datagram service. The sockets address management routines gethostbyname and getservbyname are replaced by netdir_getbyname for both connection-oriented and connectionless service.
The following XTI code sends a datagram to a receiver whose host and service names are given on the command line:
#include <stdio.h> #include <fcntl.h> #include <netconfig.h> #include <netdir.h> #include <xti.h>For more information about the functions t_open, t_bind, and t_sndudata, see t_open(3xti), t_bind(3xti), and t_sndudata(3xti)./* * the form of the command line is: * dgramsend hostname servicename */
main(argc,argv) /* XTI datagram */ int argc; char *argv[]; { int fd; struct nd_hostserve hostserv; struct nd_addrlist *addrs; struct netconfig *nconf; struct t_unitdata *ud; void *handlep;
if ( argc != 3 ) { fprintf(stderr, "USAGE: %s host service\n", argv[0]); exit(1); } hostserv.h_host = argv[1]; hostserv.h_serv = argv[2];
if ((handlep = setnetconfig()) == NULL) { nc_perror ("setnetconfig failed"); exit(1); }
/* * select an appropriate transport and * get address for remote host/service */
while ((nconf = getnetconfig(handlep)) != NULL) { if (nconf->nc_semantics == NC_TPI_CLTS && netdir_getbyname(nconf, &hostserv, &addrs) == 0) { break; } }
if (nconf == NULL) { fprintf(stderr, "no address for host %s service %s\n", argv[1], argv[2]); exit(2); }
if ((fd = t_open(nconf->nc_device, O_RDWR, NULL)) < 0) { t_error("t_open failed"); fprintf(stderr, "unable to open %s\n", nconf->nc_device); exit(3); }
if (t_bind(fd, NULL, NULL) < 0) { t_error("t_bind failed"); exit(4); }
if ((ud = (struct t_unitdata *)t_alloc(fd, T_UNITDATA, T_ALL)) == NULL ) { t_error("t_alloc of t_unitdata structure failed"); exit(5); } /* * use first address returned by netdir_getbyname() * filldata() will fill in the data to be sent */ ud->addr = addrs->n_addrs; filldata(ud->udata);
endnetconfig(handlep);
/* send the datagram */ if (t_sndudata(fd, ud) <0 ) { t_error("t_sndudata failed"); exit(6); }
exit(0); }