Tenouk C & C++ |< Winsock Prog. Example 7 | Main | Winsock Prog. Example 9 >| Site Index | Download | Linux Socket | Winsock in .NET


 

 

 

 

 

 

 

WINSOCK 2

WINDOWS SOCKET: PROGRAM EXAMPLES PART 8

 

 

 

 

 

 

 

 

 

What do we have in this chapter?

  1. sockaddr Structure

  2. SOCKADDR_STORAGE Structure

  3. Members

  4. Program Example Using sockaddr

  5. hostent Structure

  6. gethostbyaddr()

  7. Return Values

  8. gethostbyname()

  9. Return Values

  10. gethostbyname() and gethostbyaddr() Program Example

 

Winsock Tutorial

 

Winsock: Story 1

Winsock: Story 2

Winsock: Story 3

Winsock: Example 1

Winsock: Example 2

Winsock: Example 3

Winsock: Example 4

Winsock: Example 5

Winsock: Example 6

Winsock: Example 7

Winsock: Example 8

Winsock: Example 9

Winsock: Example 10

Winsock: Example 11

Winsock: Example 12

Winsock: Reference 1

Winsock: Reference 2

Winsock: Reference 3

Winsock: Reference 4

Another Complete and Advanced C & Winsock2 Programming Tutorial

My Training Period:          hours

 

Machine‚Äôs OS is standalone Windows Xp Pro with SP2 except whenever mentioned.  Compiler used was Visual C++ 2003 .Net 1.1. Beware the codes that span more than one line.  Program examples have been tested for Non Destructive Test.  All information compiled for Windows 2000 (NT5.0) above and...

 

  1. The story was discussed at Winsock introduction story.

  2. Related functions, structures and macros used in the program examples have been dumped at Winsock structure & function 1 and Winsock structure & function 2.

  3. Other related and required information (if any) not available in no. 2 can be found at MSDN & Visual C++ online reference.

 

Abilities:

  • Able to understand more Winsock implementation and operations through the APIs and program examples.

  • Able to gather, understand and use the Winsock functions, structures and macros in your programs.

  • Able to build programs that use Microsoft C/Standard C programming language and Winsock APIs.

sockaddr Structure

 

Item

Description

Structure

sockaddr.

Info

Contains socket address information. The sockaddr structure varies depending on the protocol selected. It is better to use SOCKADDR_STORAGE instead.

Definition

For IPv4:

 

struct sockaddr {

ushort sa_family;

char sa_data[14];

};

 

struct sockaddr_in {

        short   sin_family;

        u_short sin_port;

        struct  in_addr sin_addr;

        char    sin_zero[8];

};

 

The sockaddr_in6 and sockaddr_in6_old structures below are used with IPv6.

 

struct sockaddr_in6 {

        short   sin6_family;

        u_short sin6_port;

        u_long  sin6_flowinfo;

        struct  in6_addr sin6_addr;

        u_long  sin6_scope_id;

};

 

typedef struct sockaddr_in6 SOCKADDR_IN6;

typedef struct sockaddr_in6 *PSOCKADDR_IN6;

typedef struct sockaddr_in6 FAR *LPSOCKADDR_IN6;

 

 

struct sockaddr_in6_old {

        short   sin6_family;

        u_short sin6_port;

        u_long  sin6_flowinfo;

        struct  in6_addr sin6_addr; 

};

Members

As mentioned above.

Header file

<winsock2.h> for IPv4; <ws2tcpip.h> for IPv6.

Remark

The sockaddr structure varies depending on the protocol selected. Except for the sin*_family parameter, sockaddr contents are expressed in network byte order. Winsock functions using sockaddr are not strictly interpreted to be pointers to a sockaddr structure. The structure is interpreted differently in the context of different address families. The only requirements are that the first u_short is the address family and the total size of the memory buffer in bytes is namelen.  Other protocols use similar structures.

 

Table 1

 

 

Except for the sinX_family parameter, sockaddr contents are expressed in network byte order.

 

SOCKADDR_STORAGE Structure

 

The SOCKADDR_STORAGE structure also stores socket address information and the structure is sufficiently large to store IPv4 or IPv6 address information. The use of the SOCKADDR_STORAGE structure promotes protocol-family and protocol-version independence, and simplifies development. It is recommended that the SOCKADDR_STORAGE structure be used in place of the sockaddr structure. The SOCKADDR_STORAGE structure is supported on Windows Server 2003 and later.

The SOCKADDR_STORAGE structure stores socket address information. Since the SOCKADDR_STORAGE structure is sufficiently large to store address information for IPv4, IPv6, or other address families, its use promotes protocol-family and protocol-version independence and simplifies cross-platform development. So, use the SOCKADDR_STORAGE structure in place of the sockaddr structure. The syntax for SOCKADDR_STORAGE is:

typedef struct sockaddr_storage {

short ss_family;

char __ss_pad1[_SS_PAD1SIZE];

__int64 __ss_align;

char __ss_pad2[_SS_PAD2SIZE];

} SOCKADDR_STORAGE,

*PSOCKADDR_STORAGE;

Members

 

ss_family - Address family of the socket, such as AF_INET. On Windows Vista and later, the datatype for this member is defined as an ADDRESS_FAMILY.

  1. __ss_pad1 - Reserved. Defined as a 48-bit pad that ensures SOCKADDR_STORAGE achieves 64-bit alignment.

  2. __ss_align - Reserved. Used by the compiler to align the structure.

  3. __ss_pad2 - Reserved. Used by the compiler to align the structure.

 

Keep in mind that in the Microsoft Windows Software Development Kit (SDK), the version of this structure for use on Windows Vista and later is defined as SOCKADDR_STORAGE_LH. In the Windows SDK, the version of this structure to be used on earlier systems including Windows XP and later is defined as SOCKADDR_STORAGE_XP. When compiling an application if the target platform is Windows Vista and later (NTDDI_VERSION >= NTDDI_LONGHORN, _WIN32_WINNT >= 0x0600, or WINVER >= 0x0600), the SOCKADDR_STORAGE_LH structure is typedefed to the SOCKADDR_STORAGE structure. When compiling an application if the target platform is not Windows Vista and later, the SOCKADDR_STORAGE_XP structure is typedefed to the SOCKADDR_STORAGE structure. The SOCKADDR_STORAGE_LH structure defines the data type of first member of the structure as an ADDRESS_FAMILY.Application developers normally use only the ss_family member of the SOCKADDR_STORAGE. The remaining members ensure that the SOCKADDR_STORAGE can contain either an IPv6 or IPv4 address and the structure is padded appropriately to achieve 64-bit alignment. Such alignment enables protocol-specific socket address data structures to access fields within a SOCKADDR_STORAGE structure without alignment problems. With its padding, the SOCKADDR_STORAGE structure is 128 bytes in length. The first member field of the SOCKADDR_STORAGE structure is isomorphic with the sockaddr structure to enable a simplified transition from the sockaddr structure to the SOCKADDR_STORAGE structure. For more information about platform-independent SOCKADDR_STORAGE implementation recommendations, refer to RFC 2553, available at www.ietf.org.On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the SOCKADDR_STORAGE structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly.

 

Program Example Using sockaddr

 

The following example demonstrates the use of the sockaddr structure.

#include <stdio.h>

#include "winsock2.h"

 

int main()

{

  // Declare variables

  WSADATA wsaData;

  SOCKET ListenSocket;

  sockaddr_in service;

 

  // Initialize Winsock, request the Winsock 2.2

  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

  if(iResult != NO_ERROR)

    printf("Error at WSAStartup().\n");

  else

    printf("WSAStartup() is OK.\n");

 

  // Create a listening socket

  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (ListenSocket == INVALID_SOCKET)

  {

    printf("Error at socket().\n");

    WSACleanup();

    return 0;

  }

  else

     printf("socket() is OK.\n");

 

  // Bind the socket to the local IP address and port 55555

  hostent* thisHost;

  char* ip;

  u_short port;

  port = 55555;

  thisHost = gethostbyname("");

  ip = inet_ntoa(*(struct in_addr *)*thisHost->h_addr_list);

 

  printf("\nIP address is: %s.\n", ip);

  printf("Hostname is: %s.\n", thisHost->h_name);

  printf("Address type: %i.\n\n", thisHost->h_addrtype);

 

  service.sin_family = AF_INET;

  service.sin_addr.s_addr = inet_addr(ip);

  service.sin_port = htons(port);

 

  if (bind(ListenSocket,(SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)

  {

    printf("bind() failed lol!\n");

    closesocket(ListenSocket);

    return 0;

  }

  else

    printf("bind() is OK.\n");

 

  WSACleanup();

  return 0;

}

 

Sample output:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

---------------------------------------------

 

 

Figure 1

 

hostent Structure

 

Item

Description

Structure

hostent

Info

Used by functions to store information about a given host, such as host name, IP address, and so forth. An application should never attempt to modify this structure or to free any of its components. Furthermore, only one copy of the hostent structure is allocated per thread, and an application should therefore copy any information that it needs before issuing any other Windows Sockets API calls.

Definition

typedef struct hostent {

  char FAR* h_name;

  char FAR  FAR** h_aliases;

  short h_addrtype;

  short h_length;

  char FAR  FAR** h_addr_list;

} hostent;

Members

h_name - Official name of the host (PC). If using the DNS or similar resolution system, it is the Fully Qualified Domain Name (FQDN) that caused the server to return a reply. If using a local hosts file, it is the first entry after the IP address.

h_aliases - Null-terminated array of alternate names.

h_addrtype - Type of address being returned.

h_length - Length of each address, in bytes.

h_addr_list - Null-terminated list of addresses for the host. Addresses are returned in network byte order. The macro h_addr is defined to be h_addr_list[0] for compatibility with older software.

Header file

<winsock2.h>

Remark

-

 

Table 2

 

gethostbyaddr()

 

Item

Description

Function

gethostbyaddr()

Use

Retrieves the host information corresponding to a network address. The gethostbyaddr function has been deprecated by the introduction of the getnameinfo() function. Developers creating Windows Sockets 2 applications are urged to use the getnameinfo() function instead of the gethostbyaddr() function.

Prototype

struct HOSTENT* FAR gethostbyaddr( const char* addr, int len, int type);

Parameters

addr - [in] Pointer to an address in network byte order.

len - [in] Length of the address, in bytes.

type - [in] Type of the address, such as the AF_INET address family type (defined as TCP, UDP, and other associated Internet protocols). Address family types and their corresponding values are defined in the winsock2.h header file.

Return value

See below.

Include file

<winsock2.h>

Library

ws2_32.lib.

Remark

The gethostbyaddr() function returns a pointer to the hostent structure that contains the name and address corresponding to the given network address. Although gethostbyaddr is deprecated by the getnameinfo() function, gethostbyaddr is capable of returning a NetBIOS name; getnameinfo is not. Developers requiring NetBIOS name resolution may need to use gethostbyaddr() until their applications are completely independent of NetBIOS names. Note   The capability to perform reverse lookups using the gethostbyaddr function is convenient, but such lookups are considered inherently unreliable, and should be used only as a hint.

 

Table 3

 

Return Values

 

If no error occurs, gethostbyaddr() returns a pointer to the hostent structure. Otherwise, it returns a null pointer, and a specific error code can be retrieved by calling WSAGetLastError().

 

Error code

Meaning

WSANOTINITIALISED

A successful WSAStartup() call must occur before using this function.

WSAENETDOWN

The network subsystem has failed.

WSAHOST_NOT_FOUND

Authoritative answer host not found.

WSATRY_AGAIN

Non-authoritative host not found, or server failed.

WSANO_RECOVERY

A non-recoverable error occurred.

WSANO_DATA

Valid name, no data record of requested type.

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEAFNOSUPPORT

The type specified is not supported by the Windows Sockets implementation.

WSAEFAULT

The addr parameter is not a valid part of the user address space, or the len parameter is too small.

WSAEINTR

A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall().

 

Table 4

 

For program sample, see the following example.

 

gethostbyname()

 

Item

Description

Function

gethostbyname().

Use

Retrieves host information corresponding to a host name from a host database. The gethostbyname() function has been deprecated by the introduction of the getaddrinfo() function. Developers creating Windows Sockets 2 applications are urged to use the getaddrinfo() function instead of gethostbyname().

Prototype

struct hostent* FAR gethostbyname(const char* name);

Parameters

name - [in] Pointer to the null-terminated name of the host to resolve.

Return value

See below.

Include file

<winsock2.h>

Library

ws2_32.lib.

Remark

The gethostbyname() function returns a pointer to a hostent structure - a structure allocated by Windows Sockets. The hostent structure contains the results of a successful search for the host specified in the name parameter.

The application must never attempt to modify this structure or to free any of its components. Furthermore, only one copy of this structure is allocated per thread, so the application should copy any information it needs before issuing any other Windows Sockets function calls.

The gethostbyname() function cannot resolve IP address strings passed to it. Such a request is treated exactly as if an unknown host name were passed. Use inet_addr to convert an IP address string the string to an actual IP address, then use another function, gethostbyaddr(), to obtain the contents of the hostent structure. If null is provided in the name parameter, the returned string is the same as the string returned by a successful gethostname() function call. The gethostbyname() function does not check the size of the name parameter before passing the buffer. In improperly sized name parameters, heap corruption can occur.

 

Table 5

 

Return Values

 

If no error occurs, gethostbyname() returns a pointer to the hostent structure described above. Otherwise, it returns a null pointer and a specific error number can be retrieved by calling WSAGetLastError().

 

 

Error code

Meaning

WSANOTINITIALISED

A successful WSAStartup() call must occur before using this function.

WSAENETDOWN

The network subsystem has failed.

WSAHOST_NOT_FOUND

Authoritative answer host not found.

WSATRY_AGAIN

Non-authoritative host not found, or server failure.

WSANO_RECOVERY

A non-recoverable error occurred.

WSANO_DATA

Valid name, no data record of requested type.

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEFAULT

The name parameter is not a valid part of the user address space.

WSAEINTR

A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall().

 

Table 6

 

gethostbyname() and  gethostbyaddr() Program Example

 

The following examples demonstrates the use of the gethostbyname() and  gethostbyaddr() functions.

 

 

 

 

 

 

 

 

 

 

 

 

   

 

 

 

 

 

 

 

 

 

 

 

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

  // Declare variables

  WSADATA wsaData;

 

  // Initialize Winsock, request the Winsock 2.2

  int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

  if(iResult != NO_ERROR)

    printf("Error at WSAStartup().\n");

  else

    printf("WSAStartup() is OK.\n");

 

// Declare and initialize variables

hostent* remoteHost;

char* ip;

char* host_name;

unsigned int addr;

 

// User inputs name of host

printf("Input name/IP of host: ");

host_name = (char*) malloc(sizeof(char*)*128);

fgets(host_name, 128, stdin);

 

// If the user input is an alpha name for the host, use gethostbyname()

// else, gethostbyaddr() (assume IPv4) host address is a name

if (isalpha(host_name[0]))

{

  printf("\nUsing gethostbyname()...\n");

  // NULL terminated

  host_name[strlen(host_name)-1] = '\0';

  remoteHost = gethostbyname(host_name);

  ip = inet_ntoa(*(struct in_addr *)*remoteHost->h_addr_list);

  printf("IP address is: %s.\n", ip);

  printf("Address type: %i.\n\n", remoteHost->h_addrtype);

 }

else

{

  printf("\nUsing gethostbyaddr()...\n");

  addr = inet_addr(host_name);

  remoteHost = gethostbyaddr((char *)&addr, 4, AF_INET);

  printf("Hostname is: %s.\n", remoteHost->h_name);

  printf("Address type: %i.\n\n", remoteHost->h_addrtype);

}

 

if (WSAGetLastError() != 0)

{

  if (WSAGetLastError() == 11001)

  printf("Host not found...\nExiting.\n");

}

else

  printf("error #: %ld\n", WSAGetLastError());

 

// The remoteHost structure can now be used to access information about the host

  WSACleanup();

  return 0;

}

 

Sample output:

 

Figure 2

 

 

Figure 3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Linux Sockets: Story and program examples.

  2. Linux and TCP/IP.

  3. Structure, enum, union and typedef story can be found struct, enum, union & typedef tutorial.

  4. For Multibytes, Unicode characters and Localization please refer to Multibyte, Unicode and wide characters (Story) and Win32 Windows & Users tutorial (Implementation).

  5. Windows data type information is Win32 - Windows data types.

  6. A complete info on Windows socket reference from MSDN which include managed and unmanaged API doc.

  7. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 


 

Tenouk C & C++ |< Winsock Prog. Example 7 | Main | Winsock Prog. Example 9 >| Site Index | Download | Linux Socket | Winsock in .NET