Addressing a Protocol

Addressing a Protocol

For simplicity's sake, and to avoid repetition, the remaining discussion in this chapter is limited to describing how to make fundamental Winsock calls to set up communication using the Internet Protocol (IP). We chose IP because most Winsock applications developed today use it because it is widely available due to the popularity of the Internet. As we mentioned earlier, Winsock is a protocol-independent interface and specific details for using other protocols, such as IPX, are covered in Chapter 4. Also, our discussion of IP in this chapter is limited to briefly describing IP version 4 (IPv4). Chapter 3 fully describes all IP versions—IPv4 and IP version 6 (IPv6)—in greater detail.

Throughout the remainder of this chapter, we will demonstrate the basics of how to set up Winsock communication using the IPv4 protocol. IP is widely available on most computer operating systems and can be used on most local area networks (LANs), such as a small network in your office, and on wide area networks (WANs), such as the Internet. By design, IP is a connectionless protocol and doesn't guarantee data delivery. Two higher-level protocols—Transmission Control Protocol (TCP) and User Datagram Protocol (UDP)—are used for connection-oriented and connectionless data communication over IP, which we will describe later. Both TCP and UDP use IP for data transmission and are normally referred to as TCP/IP and UDP/IP. To use IPv4 in Winsock, you need understand how to address IPv4.

Addressing IPv4

In IPv4, computers are assigned an address that is represented as a 32-bit quantity. When a client wants to communicate with a server through TCP or UDP, it must specify the server's IP address along with a service port number. Also, when servers want to listen for incoming client requests, they must specify an IP address and a port number. In Winsock, applications specify IP addresses and service port information through the SOCKADDR_IN structure, which is defined as

struct sockaddr_in {     short           sin_family;     u_short         sin_port;     struct in_addr  sin_addr;     char            sin_zero[8]; };

The sin_family field must be set to AF_INET, which tells Winsock we are using the IP address family.

The sin_port field defines which TCP or UDP communication port will be used to identify a server service. Applications should be particularly careful in choosing a port because some of the available port numbers are reserved for well-known services, such as File Transfer Protocol (FTP) and Hypertext Transfer Protocol (HTTP). There are more details about choosing a port in Chapter 2.

The sin_addr field of the SOCKADDR_IN structure is used for storing an IPv4 address as a four-byte quantity, which is an unsigned long integer data type. Depending on how this field is used, it can represent a local or a remote IP address. IP addresses are normally specified in Internet standard dotted notation as “a.b.c.d.” Each letter represents a number (in decimal, octal, or hexadecimal format) for each byte and is assigned, from left to right, to the four bytes of the unsigned long integer. The final field, sin_zero, functions only as padding to make the SOCKADDR_IN structure the same size as the SOCKADDR structure.

A useful support function named inet_addr converts a dotted IP address to a 32-bit unsigned long integer quantity. The inet_addr function is defined as

unsigned long inet_addr(     const char FAR *cp  ); 

The cp field is a null-terminated character string that accepts an IP address in dotted notation. Note that this function returns an IP address as a 32-bit unsigned long integer in network-byte order.

Byte Ordering

Different computer processors represent numbers in big-endian and little-endian form, depending on how they are designed. For example, on Intel x86 processors, multibyte numbers are represented in little-endian form: the bytes are ordered from least significant to most significant. When an IP address and port number are specified as multibyte quantities in a computer, they are represented in host-byteorder. However, when IP addresses and port numbers are specified over a network, Internet networking standards specify that multibyte values must be represented in big-endian form (most significant byte to least significant), normally referred to as network-byte order.

A series of functions can be used to convert a multibyte number from host-byte order to network-byte order and vice versa. The following four API functions convert a number from host-byte to network-byte order:

u_long htonl(u_long hostlong); int WSAHtonl(     SOCKET s,     u_long hostlong,     u_long FAR * lpnetlong ); u_short htons(u_short hostshort); int WSAHtons(     SOCKET s,     u_short hostshort,     u_short FAR * lpnetshort );

The hostlong parameter of htonl and WSAHtonl is a four-byte number in host-byte order. The htonl function returns the number in network-byte order, whereas the WSAHtonl function returns the number in network-byte order through the lpnetlong parameter. The hostshort parameter of htons and WSAHtons is a two-byte number in host-byte order. The htons function returns the number as a two-byte value in network-byte order, whereas the WSAHtons function returns the number through the lpnetshort parameter.

The next four functions are the opposite of the preceding four functions; they convert network-byte order to host-byte order.

u_long ntohl(u_long netlong); int WSANtohl(     SOCKET s,     u_long netlong,     u_long FAR * lphostlong ); u_short ntohs(u_short netshort); int WSANtohs(     SOCKET s,     u_short netshort,     u_short FAR * lphostshort );

We will now demonstrate how to address IPv4 by creating a SOCKADDR_IN structure using the inet_addr and htons functions described previously.

SOCKADDR_IN InternetAddr; INT nPortId = 5150; InternetAddr.sin_family = AF_INET; // Convert the proposed dotted Internet address 136.149.3.29 // to a four-byte integer, and assign it to sin_addr InternetAddr.sin_addr.s_addr = inet_addr("136.149.3.29"); // The nPortId variable is stored in host-byte order. Convert // nPortId to network-byte order, and assign it to sin_port. InternetAddr.sin_port = htons(nPortId);

As you can probably tell, IP addresses aren't easy to remember. Most people would much rather refer to a machine (or host) by using an easy-to-remember, user-friendly host name instead of an IP address. Chapter 3 describes useful address and name resolution functions that can help you resolve a host name, such as www.somewebsite.com, to an IP address and a service name, such as FTP, to a port number using functions such as getaddrinfo, getnameinfo, gethostbyaddr, gethostbyname, gethostname, getprotobyname, getprotobynumber, get-servbyname, and getservbyport. There are also some asynchronous versions of some of these functions: WSAAsyncGetHostByAddr, WSAAsyncGetHostByName, WSAAsyncGetProtoByName, WSAAsyncGetProtoByNumber, WSAAsyncGetServBy- Name, and WSAAsyncGetServByPort.

Now that you have the basics of addressing a protocol such as IPv4, you can prepare to set up communication by creating a socket.



Network Programming for Microsoft Windows
Network Programming for Microsoft Windows (Microsoft Professional Series)
ISBN: 0735605602
EAN: 2147483647
Year: 2001
Pages: 172
Authors: Anthony Jones

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net