Programming with sockets

Manipulating byte order

With the support routines described above, an Internet application program should rarely have to deal directly with addresses. This allows services to be developed as much as possible in a network independent fashion. It is clear, however, that purging all network dependencies is very difficult. So long as the user is required to supply network addresses when naming services and sockets there will always be some network dependency in a program. For example, the normal code included in client programs, such as the remote login program, is of the form shown in this section. (This example will be considered in more detail in ``Client/Server model''.)

Aside from the address-related database routines, there are several other routines available in the run-time library that are of interest to users. These are intended mostly to simplify manipulation of names and addresses. ``Runtime library routines'' summarizes the routines for manipulating variable length byte strings and handling byte swapping of network addresses and values.

Runtime library routines

Call Synopsis
memcmp(s1, s2, n) Compare byte-strings; 0 if same, not 0 otherwise
memcpy(s1, s2, n) Copy n bytes from s2 to s1
memset(base, value, n) Set n bytes to value starting at base
htonl(val) 32-bit quantity from host into network byte order
htons(val) 16-bit quantity from host into network byte order
ntohl(val) 32-bit quantity from network into host byte order
ntohs(val) 16-bit quantity from network into host byte order
The byte swapping routines are provided because the operating system expects addresses to be supplied in network order. On some architectures, such as the VAX(TM) or Intel®, host byte ordering is different from network byte ordering. Consequently, programs are sometimes required to byte swap quantities. The library routines that return network addresses provide them in network order so that they may simply be copied into the structures provided to the system. Users should therefore encounter byte swapping problems only when interpreting network addresses. For example, the following code will print out an Internet port:

   printf("port number %d\n", ntohs(sp->s_port));
On machine architectures for which conversion is not needed, these macros return their arguments unchanged.
   #include <sys/types.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <stdio.h>
   #include <netdb.h>
   main(argc, argv)
   	int argc;
   	char *argv[];
   	struct sockaddr_in server;
   	struct servent *sp;
   	struct hostent *hp;
   	int s;
   	sp = getservbyname("login", "tcp");
   	if (sp == NULL) {
   		fprintf(stderr, "rlogin: tcp/login: unknown service\n");
   	hp = gethostbyname(argv[1]);
   	if (hp == NULL) {
   		fprintf(stderr, "rlogin: %s: unknown host\n", argv[1]);
   	memset((char *)&server, 0, sizeof(server));
   	memcpy((char *)&server.sin_addr, hp->h_addr, hp->h_length);
   	server.sin_len = sizeof(server);
   	server.sin_family = hp->h_addrtype;
   	server.sin_port = sp->s_port;
   	s = socket(AF_INET, SOCK_STREAM, 0);
   	if (s < 0) {
   		perror("rlogin: socket");
   	/* Connect does the bind for us */
   	if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0) {
   		perror("rlogin: connect");

© 2005 The SCO Group, Inc. All rights reserved.
SCO OpenServer Release 6.0.0 -- 02 June 2005