< I/O Completion Port Client-Server Example | Scalability Main | Chap 7: Socket Options & IOCTLs >
What do we have in this chapter?
Add the resolve.h header file.
Add the source code
// Common routines for resolving addresses and hostnames
// Files:
// resolve.h - Header file for common routines
// Description:
// This file contains common name resolution and name printing
// routines and is used by many of the samples.
//
#ifndef _RESOLVE_H_
#define _RESOLVE_H_
#ifdef _cplusplus
extern "C" {
#endif
int PrintAddress(SOCKADDR *sa, int salen);
int FormatAddress(SOCKADDR *sa, int salen, char *addrbuf, int addrbuflen);
struct addrinfo *ResolveAddress(char *addr, char *port, int af, int type, int proto);
#ifdef _cplusplus
}
#endif
#endif
Add the definition file, resolve.cpp for resolve.h header file
Add the source code.
// Common routines for resolving addresses and hostnames
//
// Files:
// resolve.cpp - Common routines
// resolve.h - Header file for common routines
//
// Description:
// This file contains common name resolution and name printing
// routines and is used by many of the samples.
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include "resolve.h"
// Function: PrintAddress
// Description:
// This routine takes a SOCKADDR structure and its length and prints
// converts it to a string representation. This string is printed to the console via stdout.
int PrintAddress(SOCKADDR *sa, int salen)
{
char host[NI_MAXHOST], serv[NI_MAXSERV];
int hostlen = NI_MAXHOST, servlen = NI_MAXSERV, rc;
rc = getnameinfo(sa, salen, host, hostlen, serv, servlen,NI_NUMERICHOST | NI_NUMERICSERV);
if (rc != 0)
{
fprintf(stderr, "%s: getnameinfo() failed with error code %d\n", __FILE__, rc);
return rc;
}
else
printf("getnameinfo() is OK!\n");
// If the port is zero then don't print it
if (strcmp(serv, "0") != 0)
{
if (sa->sa_family == AF_INET)
printf("[%s]:%s", host, serv);
else
printf("%s:%s", host, serv);
}
else
printf("%s", host);
return NO_ERROR;
}
// Function: FormatAddress
// Description:
// This is similar to the PrintAddress function except that instead of
// printing the string address to the console, it is formatted into the supplied string buffer.
int FormatAddress(SOCKADDR *sa, int salen, char *addrbuf, int addrbuflen)
{
char host[NI_MAXHOST], serv[NI_MAXSERV];
int hostlen = NI_MAXHOST, servlen = NI_MAXSERV, rc;
rc = getnameinfo(sa, salen, host, hostlen, serv, servlen, NI_NUMERICHOST | NI_NUMERICSERV);
if (rc != 0)
{
fprintf(stderr, "%s: getnameinfo() failed with error code %d\n", __FILE__, rc);
return rc;
}
else
printf("getnameinfo() is OK!\n");
if ( (strlen(host) + strlen(serv) + 1) > (unsigned)addrbuflen)
return WSAEFAULT;
if (sa->sa_family == AF_INET)
sprintf_s(addrbuf, sizeof(addrbuf), "%s:%s", host, serv);
else if (sa->sa_family == AF_INET6)
sprintf_s(addrbuf, sizeof(addrbuf), "[%s]:%s", host, serv);
else
addrbuf[0] = '\0';
return NO_ERROR;
}
// Function: ResolveAddress
// Description:
// This routine resolves the specified address and returns a list of addrinfo
// structure containing SOCKADDR structures representing the resolved addresses.
// Note that if 'addr' is non-NULL, then getaddrinfo will resolve it whether
// it is a string literal address or a hostname.
struct addrinfo *ResolveAddress(char *addr, char *port, int af, int type, int proto)
{
struct addrinfo hints, *res = NULL;
int rc;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = ((addr) ? 0 : AI_PASSIVE);
hints.ai_family = af;
hints.ai_socktype = type;
hints.ai_protocol = proto;
rc = getaddrinfo(addr, port, &hints, &res);
if (rc != 0)
{
printf("Invalid address %s, getaddrinfo() failed with error code %d\n", addr, rc);
return NULL;
}
else
printf("getaddrinfo() should be fine!\n");
return res;
}
Build and run the project.
Let test this program with the test client program created in the previous chapter. Firstly, run this server program.
Then run the client program several times with different –n values.
The server program sample output is shown below. It is very interesting if you can test this program in real network with many clients.
< I/O Completion Port Client-Server Example | Scalability Main | Chap 7: Socket Options & IOCTLs >