Previous | Contents |
If your application compares an IP address to the wildcard address, the in6_addr structure changes (see Section 7.3.1) will change the comparison of int quantities to a comparison of structures. This will break the code and cause compiler errors.
Make either of the following changes to your application, as needed:
AF_INET Code | AF_INET6 Code |
---|---|
(addr->s_addr == INADDR_ANY) | IN6_IS_ADDR_UNSPECIFIED(addr) |
AF_INET Code | AF_INET6 Code |
---|---|
(addr->s_addr == INADDR_ANY) | (memcmp(addr, in6addr_any, sizeof(struct in6_addr)) == 0) |
If your application uses int data types to hold IP addresses, the in6_addr structure changes (see Section 7.3.1 ) will change the assignment. This will break the code and cause compiler errors.
Make the following changes to your application, as needed:
AF_INET Code | AF_INET6 Code |
---|---|
struct in_addr foo;
int bar; . . . bar = foo.s_addr; |
struct in6_addr foo;
struct in6_addr bar; . . . bar = foo; |
If your application uses functions that return IP addresses as int data types, the in6_addr structure changes (see Section 7.3.1 will change the destination of the return value from an int to an array of char. This will break the code and cause compiler errors.
Make the following changes to your application, as needed:
AF_INET Code | AF_INET6 Code |
---|---|
struct in_addr *addr;
addr->s_addr = foo( xxx); |
struct in6_addr *
addr;
foo( xxx, addr); |
If your application uses IPv4 IP-level socket options, change them to
the corresponding IPv6 options.
7.6 Sample Client/Server Programs
This section contains sample client and server programs that demonstrate the differences between IPv4 and IPv6 coding conventions:
To build the examples, use the following commands:
$ DEFINE DECC$SYSTEM_INCLUDE TCPIP$EXAMPLES: $ DEFINE ARPA TCPIP$EXAMPLES: $ DEFINE NET TCPIP$EXAMPLES: $ DEFINE NETINET TCPIP$EXAMPLES: $ DEFINE SYS TCPIP$EXAMPLES: $ CC/NOOPT/STANDARD=VAXC/PREFIX=ALL/EXTERN_MODEL=STRICT_REFDEF/DEFINE=(INET6,_SOCKADDR_LEN) client.c $ LINK/MAP client,TCPIP$LIBRARY:TCPIP$LIB/lib $ CC/NOOPT/STANDARD=VAXC/PREFIX=ALL/EXTERN_MODEL=STRICT_REFDEF/DEFINE=(INET6,_SOCKADDR_LEN) server.c $ LINK/MAP server,TCPIP$LIBRARY:TCPIP$LIB/lib |
This section contains a client and a server program that use AF_INET
sockets.
7.6.1.1 Client Program
The following is a sample client program that you can build, compile and run on your system. The program sends a request to and receives a response from the system specified on the command line.
/* * ***************************************************************** * * * * * Copyright 2000 Compaq Computer Corporation * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Compaq * * * Computer Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Compaq Computer * * * Corporation. * * * * * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * * * by the U.S. Government is subject to restrictions as set * * * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * * * or in FAR 52.227-19, as applicable. * * * * * ***************************************************************** */ #include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <stdlib.h> #include <arpa/inet.h> #define SERVER_PORT 7639 #define CLIENT_PORT 7739 #define MAXBUFSIZE 4096 int main ( int argc, char **argv ) { int s; char databuf[MAXBUFSIZE]; int dcount; struct sockaddr_in serveraddr; (1) struct sockaddr_in clientaddr; int serveraddrlen; const char *ap; const char *request = "this is the client's request"; struct hostent *hp; char *server; if (argc < 2) { printf("Usage: client <server>\n"); exit(1); } server = argv[1]; bzero((char *) &serveraddr, sizeof(struct sockaddr_in)); (2) serveraddr.sin_family = AF_INET; if ((hp = gethostbyname(server)) == NULL) { (3) printf("unknown host: %s\n", server); exit(2); } serveraddr.sin_port = htons(SERVER_PORT); while (hp->h_addr_list[0] != NULL) { if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { (4) perror("socket"); exit(3); } memcpy(&serveraddr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); if (connect(s, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { perror("connect"); close(s); hp->h_addr_list++; continue; } break; } if (send(s, request, strlen(request), 0) < 0) { (5) perror("send"); exit(5); } dcount = recv(s, databuf, sizeof(databuf), 0); if (dcount < 0) { perror("recv"); exit(6); } databuf[dcount] = '\0'; hp = gethostbyaddr((char *)&serveraddr.sin_addr.s_addr, (6) sizeof(serveraddr.sin_addr.s_addr), AF_INET); ap = inet_ntoa(serveraddr.sin_addr); (7) printf("Response received from"); if (hp != NULL) printf(" %s", hp->h_name); if (ap != NULL) printf(" (%s)", ap); printf(": %s\n", databuf); close(s); } |
The following is a sample server program that you can build, compile, and run on your system. The program receives requests from and sends responses to client programs on other systems.
/* * ***************************************************************** * * * * * Copyright 2000 Compaq Computer Corporation * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Compaq * * * Computer Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Compaq Computer * * * Corporation. * * * * * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * * * by the U.S. Government is subject to restrictions as set * * * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * * * or in FAR 52.227-19, as applicable. * * * * * ***************************************************************** */ #include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <stdlib.h> #include <arpa/inet.h> #define SERVER_PORT 7639 #define CLIENT_PORT 7739 #define MAXBUFSIZE 4096 int main ( int argc, char **argv ) { int s; char databuf[MAXBUFSIZE]; int dcount; struct sockaddr_in serveraddr; (1) struct sockaddr_in clientaddr; int clientaddrlen; struct hostent *hp; const char *ap; const char *response = "this is the server's response"; u_short port; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { (2) perror("socket"); exit(1); } bzero((char *) &serveraddr, sizeof(struct sockaddr_in)); (3) serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); serveraddr.sin_port = htons(SERVER_PORT); if (bind(s, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { perror("bind"); exit(2); } if (listen(s, SOMAXCONN) < 0) { perror("Listen"); close(s); exit(3); while (1) { int new_s; clientaddrlen = sizeof(clientaddr); new_s = accept(s, (Struct sockaddr*)&clientaddr, &clientaddrlen); dcount = recv(new_s, databuf, sizeof(databuf), 0); if (dcount <= 0) { perror("recv"); close(new_s); continue; } databuf[dcount] = '\0'; hp = gethostbyaddr((char *)&clientaddr.sin_addr.s_addr, (4) sizeof(clientaddr.sin_addr.s_addr), AF_INET); ap = inet_ntoa(clientaddr.sin_addr); (5) port = ntohs(clientaddr.sin_port); printf("Request received from"); if (hp != NULL) printf(" %s", hp->h_name); if (ap != NULL) printf(" (%s)", ap); printf(" port %d \"%s\"\n", port, databuf); if (send(new_s, response, strlen(response), 0) < 0) { perror("send"); continue; } close(new_s); } close(s); } |
This section contains a client and a server program that use AF_INET6
sockets.
7.6.2.1 Client Program
The following is a sample client program that you can build, compile and rin on your system. The program sends a request to and receives a response from the system specified on the command line.
/* * ***************************************************************** * * * * * Copyright 2000 Compaq Computer Corporation * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Compaq * * * Computer Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Compaq Computer * * * Corporation. * * * * * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * * * by the U.S. Government is subject to restrictions as set * * * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * * * or in FAR 52.227-19, as applicable. * * * * * ***************************************************************** */ #include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <stdlib.h> #include <arpa/inet.h> #define SERVER_PORT 7639 #define CLIENT_PORT 7739 #define MAXBUFSIZE 4096 int main ( int argc, char **argv ) { int s; char databuf[MAXBUFSIZE]; int dcount; struct addrinfo *server_info; (1) struct addrinfo *cur_info; struct addrinfo hints; struct sockaddr_in6 serveraddr; char addrbuf[INET6_ADDRSTRLEN]; char node[MAXDNAME]; char service[MAXDNAME]; int ni; int err; int serveraddrlen; const char *request = "this is the client's request"; char *server; if (argc < 2) { printf("Usage: client client <server>\n"); exit(1); } server = argv[1]; bzero((char *) &hints, sizeof(hints)); (2) hints.ai_family = AF_INET6; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_DEFAULT; sprintf(service, "%d", SERVER_PORT); err = getaddrinfo(server, service, &hints, &server_info); (3) if (err != 0) { if (err == EAI_SYSTEM) perror("getaddrinfo"); else printf("%s", gai_strerror(err0)); exit(2); } cur_info = server_info; while (cur_info != NULL) { if ((s = socket(cur_info->ai_family, cur_info->ai_socktype, 0)) < 0) { (4) perror("socket"); exit(3); } if (connect(s, cur_info->ai_addr, cur_info->ai_addrlen) <0 { close(s); cur_info = cur_info->ai_next; continue; } break; } freeaddrinfo(server_info); (5) if (send(s, request, strlen(request), 0) < 0) { (6) perror("send"); exit(5); } dcount = recv(s, databuf, sizeof(databuf), 0); if (dcount < 0) { perror("recv"); exit(6); } databuf[dcount] = '\0'; serveraddrlen = sizeof(serveraddr); if (getpeername(s, (struct sockaddr*) &serveraddr, &serveraddrlen) < 0 { perror("getpeername"); exit(7); } printf("Response received from"); ni = getnameinfo((struct sockaddr*)&serveraddr, serveraddrlen, (7) node, sizeof(node), NULL, 0, NI_NAMEREQD); if (ni == 0) printf(" %s", node); ni = getnameinfo((struct sockaddr*)&serveraddr, serveraddrlen, (8) addrbuf, sizeof(addrbuf), NULL, 0, NI_NUMERICHOST); if (ni == 0) printf(" (%s)", addrbuf); printf(": %s\n", databuf); close(s); } |
The following is a sample server program that you can build, compile, and run on your system. The program receives requests from and sends responses to client programs on other systems.
/* * ***************************************************************** * * * * * Copyright 2000 Compaq Computer Corporation * * * * * * The software contained on this media is proprietary to * * * and embodies the confidential technology of Compaq * * * Computer Corporation. Possession, use, duplication or * * * dissemination of the software and media is authorized only * * * pursuant to a valid written license from Compaq Computer * * * Corporation. * * * * * * RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure * * * by the U.S. Government is subject to restrictions as set * * * forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, * * * or in FAR 52.227-19, as applicable. * * * * * ***************************************************************** */ #include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <stdio.h> #include <signal.h> #include <stdlib.h> #include <arpa/inet.h> #define SERVER_PORT 7639 #define CLIENT_PORT 7739 #define MAXBUFSIZE 4096 int main ( int argc, char **argv ) { int s; char databuf[MAXBUFSIZE]; int dcount; struct sockaddr_in6 serveraddr; (1) struct storage clientaddr; char addrbuf[INET6_ADDRSTRLEN]; char node[MAXDNAME]; char port[MAXDNAME]; int err; int ni; int clientaddrlen; const char *response = "this is the server's response"; if ((s = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { (2) perror("socket"); exit(1); } bzero((char *) &serveraddr, sizeof(struct sockaddr_in6)); (3) serveraddr.sin6_family = AF_INET6; serveraddr.sin6_addr = in6addr_any; serveraddr.sin6_port = htons(SERVER_PORT); if (bind(s, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { perror("bind"); exit(2); } if (listen(s, SOMAXCONN) < 0) { perror("listen"); close(s); exit(3); } while (1) { int new_s; clientaddrlen = sizeof(clientaddr); bzero((char *)&clientaddr, clientaddrlen); (4) new_s = accept(s, (struct sockaddr*)&clientaddr, &clientaddrlen); if (new_s < 0) { perror("accept"); continue; } dcount = recv(s, databuf, sizeof(databuf), 0); if (dcount <= 0) { perror("recv"); close(new_s); continue; } databuf[dcount] = '\0'; printf("Request received from"); ni = getnameinfo((struct sockaddr *)&clientaddr, (5) clientaddrlen, node, sizeof(node), NULL, 0, NI_NAMEREQD); if (ni == 0) printf(" %s", node); ni = getnameinfo((struct sockaddr *)&clientaddr, (6) clientaddrlen, addrbuf, sizeof(addrbuf), port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); if (ni == 0) printf(" (%s) port %d, addrbuf, port); printf(" \"%s\"\n", port, databuf); if (send(new_s, response, strlen(response), 0) < 0) { perror("send"); close(new_s); continue; } close(new_s); } close(s); } |
This section contains sample output from the preceding server and client programs. The server program makes and receives all requests on an AF_INET6 socket using sockaddr_in6 . For requests received over IPv4, sockaddr_in6 contains an IPv4-mapped IPv6 address.
The following example shows a client program running on node hostb6 and sending a request to node hosta6. The program uses an AF_INET6 socket. The node hosta6 has the IPv6 address 3ffe:1200::a00:2bff:fe97:7be0 in the Domain Name System (DNS).
$ client :== $client.exe $ client hosta6 Response received from hosta6.ipv6.corp.example (3ffe:1200::a00:2bff:fe97:7be0): this is the server's response |
On the server node, the following example shows the server program invocation and the request received from the client node hostb6:
$ run server Request received from hostb6.ipv6.corp.example (3ffe:1200::a00:2bff:fe2d:02b2 port 7739 "this is the client's request" |
The following example shows the client program running on node hostb and sending a request to node hosta. The program uses an AF_INET6 socket. The hosta node has the IPv4 address 10.10.10.13 in the DNS.
$ client :== $client.exe $ client hosta Response received from hosta.corp.example (::ffff:10.10.10.13): this is the server's response |
On the server node, the following example shows the server program invocation and the request received from the client node hostb:
$ run server Request received from hostb.corp.example (::ffff:10.10.10.251) port 7739 "this is the client's request" |
The following example shows the client program running on node hostc and sending a request to node hosta. The program was built and run on an IPv4-only system using an AF_INET socket.
$ client :== $client.exe $ client hosta Response received from hosta.corp.example (10.10.10.13): this is the server's response |
On the server node, the following example shows the server program invocation and the request received from the client node hostc:
$ run server Request received from hostc.corp.example (::ffff:10.10.10.63) port 7739 "this is the client's request" |
Previous | Next | Contents |