hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


HP TCP/IP Services for OpenVMS

HP TCP/IP Services for OpenVMS
Sockets API and System Services Programming


Previous Contents Index

  1. Declares sockaddr_in structures.
  2. Declares hostent structure.
  3. Clears the server sockaddr_in structure and sets values for fields of the structure.
  4. Creates an AF_INET socket.
  5. Calls gethostbyaddr() to retrieve client name.

E.6.2 Programs Using AF_INET6 Sockets

This section contains a client and a server program that use AF_INET6 sockets.

E.6.2.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.


#include <in.h>                       /* define internet related constants,   */ 
                                      /* functions, and structures            */ 
#include <inet.h>                     /* define network address info          */ 
 
#include <netdb.h>                    /* define network database library info */ 
 
#include <socket.h>                   /* define BSD 4.x socket api            */ 
#include <stdio.h>                    /* define standard i/o functions        */ 
#include <stdlib.h>                   /* define standard library functions    */ 
#include <string.h>                   /* define string handling functions     */ 
 
#include <unixio.h>                   /* define unix i/o                      */ 
 
 
#define BUFSZ           1024          /* user input buffer size               */ 
#define SERV_PORTNUM    "12345"       /* server port number string            */ 
 
 
int main( void );                     /* client main                          */ 
void get_serv_addr( struct addrinfo *hints, struct addrinfo **res );(1)
                                      /* get server host address              */ 
 
int 
main( void ) 
{ 
    int sockfd;                       /* connection socket descriptor        */ 
 
    char buf[512];                    /* client data buffer                  */ 
 
    struct addrinfo hints;            /* input values to direct operation    */ 
    struct addrinfo *res;(2)           /* linked list of addrinfo structs     */ 
 
    memset( &hints, 0, sizeof(hints) );(3)
    hints.ai_family = AF_INET6; 
    hints.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_CANONNAME; 
    hints.ai_protocol = IPPROTO_TCP; 
    hints.ai_socktype = SOCK_STREAM; 
    get_serv_addr( &hints, &res );(4)
 
    if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0 )(5)
        { 
        perror( "Failed to create socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Initiated connection to host: %s, port: %d\n", 
            res->ai_canonname, 
            htons(((struct sockaddr_in6 *)res->ai_addr)->sin6_port)(6) ); 
 
    if ( connect(sockfd, res->ai_addr, res->ai_addrlen) < 0 )(7)
        { 
        perror( "Failed to connect to server" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( recv(sockfd, buf, sizeof(buf), 0) < 0 ) 
        { 
        perror( "Failed to read data from server connection" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Data received: %s\n", buf ); /* output client's data buffer   */ 
 
    if ( shutdown(sockfd, 2) < 0 ) 
        { 
        perror( "Failed to shutdown server connection" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( close(sockfd) < 0 ) 
        { 
        perror( "Failed to close socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    exit( EXIT_SUCCESS ); 
} 
 
void 
get_serv_addr( struct addrinfo *hints, struct addrinfo **res )(8)
{ 
    int gai_error;                      /* return value of getaddrinfo()  */ 
    char buf[BUFSZ];                    /* input data buffer              */ 
    const char *port = SERV_PORTNUM;    /* server port number             */ 
 
    while ( TRUE ) 
        { 
        printf( "Enter remote host: " ); 
 
        if ( fgets(buf, sizeof(buf), stdin) == NULL ) 
            { 
            printf( "Failed to read User input\n" ); 
            exit( EXIT_FAILURE ); 
            } 
 
        buf[strlen(buf)-1] = 0; 
 
        gai_error = getaddrinfo( buf, port, hints, res );(9)
        if ( gai_error ) 
          printf( "Failed to resolve name or address: %s\n", 
                  gai_strerror(gai_error)(10)
                  ); 
 else 
     break; 
        } 
} 
 

  1. Function prototype for server host address/name translation function.
  2. Declares addrinfo structures.
  3. Clears the addrinfo structure and sets values for fields of the structure.
  4. Calls get_serv_addr() passing pointers to the input and output addrinfo structures.
  5. Creates an AF_INET6 socket.
  6. Uses values from the output addrinfo structure for host name and port.
  7. Calls connect() using values from the output addrinfo structure.
  8. Retrieves the server host's address from the user and stores it in the addrinfo structure. The user can specify a server host by using any of the following:
  9. Calls getaddrinfo() to retrieve the server host's name or address.
  10. Calls gai_strerror() to convert one of the EAI_xx return values to a string describing the error.

E.6.2.2 Server Program

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.


#include <in.h>                       /* define internet related constants, 
                                      /* functions, and structures            */ 
#include <inet.h>                     /* define network address info          */ 
 
#include <netdb.h>                    /* define network database library info */ 
 
#include <socket.h>                   /* define BSD 4.x socket api            */ 
#include <stdio.h>                    /* define standard i/o functions        */ 
#include <stdlib.h>                   /* define standard library functions    */ 
#include <string.h>                   /* define string handling functions     */ 
 
#include <unixio.h>                   /* define unix i/o                      */ 
 
#define SERV_BACKLOG    1             /* server backlog                       */ 
#define SERV_PORTNUM    12345         /* server port number                   */ 
 
int  main( void );                    /* server main                          */ 
 
int 
main( void ) 
{ 
    int optval = 1;                   /* SO_REUSEADDR'S option value (on)     */ 
 
    int conn_sockfd;                  /* connection socket descriptor         */ 
    int listen_sockfd;                /* listen socket descriptor             */ 
    int gni_error;(1)                  /* return status for getnameinfo()      */ 
 
    unsigned int client_addrlen;      /* returned length of client socket     */ 
                                      /* address structure                    */ 
    struct sockaddr_in6 client_addr;  /* client socket address structure      */ 
    struct sockaddr_in6 serv_addr;(2)  /* server socket address structure      */ 
 
    char buf[] = "Hello, world!";     /* server data buffer                   */ 
    char node[NI_MAXHOST];(3)          /* buffer to receive node name          */ 
    char port[NI_MAXHOST];            /* buffer to receive port number        */ 
    char addrbuf[INET6_ADDRSTRLEN];   /* buffer to receive host's address     */ 
 
    memset( &client_addr, 0, sizeof(client_addr) ); 
 
    memset( &serv_addr, 0, sizeof(serv_addr) );(4)
    serv_addr.sin6_family      = AF_INET6; 
    serv_addr.sin6_port        = htons( SERV_PORTNUM ); 
    serv_addr.sin6_addr        = in6addr_any; 
 
    if ( (listen_sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0 )(5)
        { 
        perror( "Failed to create socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( setsockopt(listen_sockfd, 
         SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0 ) 
        { 
        perror( "Failed to set socket option" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( bind(listen_sockfd, 
         (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) 
        { 
        perror( "Failed to bind socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( listen(listen_sockfd, SERV_BACKLOG) < 0 ) 
        { 
        perror( "Failed to set socket passive" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Waiting for a client connection on port: %d\n", 
            ntohs(serv_addr.sin6_port) 
          ); 
 
    client_addrlen = sizeof(client_addr); 
 
    conn_sockfd = accept( listen_sockfd, 
                          (struct sockaddr *) &client_addr, 
                          &client_addrlen 
                          ); 
    if ( conn_sockfd < 0 ) 
        { 
        perror( "Failed to accept client connection" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    gni_error = getnameinfo( (struct sockaddr *)&client_addr,client_addrlen, (6)
                             node, sizeof(node), NULL, 0, NI_NAMEREQD 
                             ); 
    if ( gni_error ) 
        { 
        printf( "Failed to translate client address: %s\n", 
                gai_strerror(gni_error) (7)
              ); 
        exit( EXIT_FAILURE ); 
        } 
 
    gni_error = getnameinfo( (struct sockaddr *)&client_addr, client_addrlen, 
                             addrbuf, sizeof(addrbuf), port, sizeof(port), 
                             NI_NUMERICHOST | NI_NUMERICSERV (8)
                           ); 
    if ( gni_error ) 
        { 
        printf( "Failed to translate client address and/or port: %s\n", 
                gai_strerror(gni_error) 
              ); 
 exit( EXIT_FAILURE ); 
        } 
 
    printf( "Accepted connection from host: %s (%s), port: %s\n", 
            node, addrbuf, port 
          ); 
 
    if ( send(conn_sockfd, buf, sizeof(buf), 0) < 0 ) 
        { 
        perror( "Failed to write data to client connection" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    printf( "Data sent: %s\n", buf );    /* output server's data buffer       */ 
 
    if ( shutdown(conn_sockfd, 2) < 0 ) 
        { 
        perror( "Failed to shutdown client connection" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( close(conn_sockfd) < 0 ) 
        { 
        perror( "Failed to close socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    if ( close(listen_sockfd) < 0 ) 
        { 
        perror( "Failed to close socket" ); 
        exit( EXIT_FAILURE ); 
        } 
 
    exit( EXIT_SUCCESS ); 
} 
 

  1. Declares variable for getnameinfo() return value
  2. Declares sockaddr_in6 structures
  3. Declares buffers to receive client's name, port number, and address for calls to getnameinfo() .
  4. Clears the server sockaddr_in6 structure and sets values for fields of the structure.
  5. Creates an AF_INET6 socket.
  6. Calls getnameinfo() to retrieve client name. This is for message displaying purposes only and is not necessary for proper functioning of the server.
  7. Calls gai_strerror() to convert one of the EAI_xxx return values to a string describing the error.
  8. Calls getnameinfo() to retrieve client address and port number. This is for message displaying purposes only and is not necessary for proper functioning of the server.

E.6.3 Sample Program Output

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).


$ run client.exe 
Enter remote host: hosta6 
Initiated connection to host: hosta6.ipv6.corp.example, port: 12345 
Data received: Hello, world! 
$ 

On the server node, the following example shows the server program invocation and the request received from the client node hostb6 :


$ run server.exe 
Waiting for a client connection on port: 12345 
Accepted connection from host: hostb6.ipv6.corp.example 
(3ffe:1200::a00:2bff:fe97:7be0), port: 49174 
Data sent: Hello, world! 
$ 

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 only an IPv4 address in the DNS.


$ run client.exe 
Enter remote host: hosta 
Initiated connection to host: hosta.corp.example, port 12345 
Data received: Hello, world! 
$ 

On the server node, the following example shows the server program invocation and the request received from the client node hostb :


$ run server.exe 
Waiting for a client connection on port: 12345 
Accepted connection from host: hostb.corp.example (::ffff:10.10.10.251), port: 49175 
Data sent: Hello, world! 
$ 

The following example shows the client program running on node hostb6 and sending a request to node hosta6 using its link-local address fe80::a00:2bff:fe97:7be0. The program uses an AF_INET6 socket.


$ run client.exe 
Enter remote host: fe80::a00:2bff:fe97:7be0 
Initiated connection to host: fe80::a00:2bff:fe97:7be0, port: 12345 
Data received: Hello, world! 
$ 

On the server node, the following example shows the server program invocation and the request received from the client node hostb6 .


$ run server.exe 
Waiting for a client connection on port: 12345 
Accepted connection from host: hosta6.ipv6.corp.example%WE0 
(fe80::a00:2bff:fe97:7be0%WE0), port: 49177 
Data sent: Hello, world! 
$ 


Index Contents