My Training Period: xx hours
Note: Program examples if any, compiled usinggcc on Linux Fedora Core 3 machine with several update, as normal user. The Fedora machine used for the testing having the "No Stack Execute" disabled and the SELinux set to default configuration.
sendto() and recvfrom() for DATAGRAM (UDP)
A sample of the client socket call flow
A sample of the server socket call flow
Network Integers versus Host Integers
Little Endian and big Endian issue regarding the use of the different processor architectures.
Usually integers are either most-significant byte first or least-significant byte first.
On Intel based machines the hex value 0x01020304 would be stored in 4 successive bytes as:
04, 03, 02, 01. This is a little endian.
On an Most Significant Bit (MSB)-first (big endian) machine (IBM RS6000), this would be: 01, 02, 03, 04.
It is important to use network byte order (MSB-first) and the conversion functions available for this task are listed below:
Host to network short.
Network to host short.
Host to network long.
Network to host long.
Use these functions to write portable network code.
Fortunately for you, there are a bunch of functions that allow you to manipulate IP addresses. No need to figure them out by hand and stuff them in a long with the« operator.
First, let’s say you have a:
struct sockaddr_in ina
And you have an IP address "10.12.110.57" that you want to store into it.
The function you want to use,inet_addr(), converts an IP address in numbers-and-dots notation into an unsigned long. The assignment can be made as follows:
ina.sin_addr.s_addr = inet_addr("10.12.110.57");
Notice that inet_addr() returns the address in Network Byte Order already so you don’t have to call htonl().
Now, the above code snippet isn’t very robust because there is no error checking. inet_addr() returns-1 on error.
For binary numbers (unsigned)-1 just happens to correspond to the IP address 255.255.255.255! That’s the broadcast address! Remember to do your error checking properly.
Actually, there’s a cleaner interface you can use instead of inet_addr(): it’s called inet_aton() ("aton" means "ascii to network"):
int inet_aton(const char *cp, struct in_addr *inp);
And here’s a sample usage, while packing a struct sockaddr_inis shown below:
struct sockaddr_in my_addr;
/* host byte order */
my_addr.sin_family = AF_INET;
/* short, network byte order */
my_addr.sin_port = htons(MYPORT);
/* zero the rest of the struct */
memset(&(my_addr.sin_zero), 0, 8);
inet_aton(), unlike practically every other socket-related function, returns non-zero on success, and zero on failure. And the address is passed back in inp.
Unfortunately, not all platforms implementinet_aton() so, although its use is preferred, normally the older more common inet_addr() is used.
All right, now you can convert string IP addresses to their binary representations. What about the other way around?
What if you have a struct in_addr and you want to print it in numbers-and-dots notation? In this case, you’ll want to use the function inet_ntoa() ("ntoa" means "network to ascii") something like this:
That will print the IP address. Note that inet_ntoa() takes a struct in_addr as an argument, not a long. Also notice that it returns a pointer to a char.
This points to a statically stored char array within inet_ntoa() so that each time you call inet_ntoa() it will overwrite the last IP address you asked for. For example:
char *a1, *a2;
a1 = inet_ntoa(ina1.sin_addr); /* this is 192.168.4.1 */
a2 = inet_ntoa(ina2.sin_addr); /* this is 10.11.110.55 */
printf("address 1: %s\n", a1);
printf("address 2: %s\n", a2);
address 1: 10.11.110.55
address 2: 10.11.110.55
If you need to save the address,strcpy() it to your own character array.
Let see, what we have covered till now.
Socket Library Functions
Startup / close.
Network configuration lookup:
Ports for services.
Primary Socket Calls
Network Database Administration functions
gethostbyname() - given a hostname, returns a structure which specifies its DNS name(s) and IP address (es).
getservbyname() - given service name and protocol, returns a structure which specifies its name(s) and its port address.
gethostname() - returns hostname of local host.
Socket Utility Functions
Convert short/long from network byte order (big endian) to host byte order.
Convert short/long from host byte order to network byte order.
Convert 32-bit IP address (network byte order to/from a dotted decimal string).
Print error message (based on “errno”) to stderr.
Print error message for gethostbyname() to stderr (used with DNS).
Primary Header Files
Include file sequence may affect processing (order is important!). Other header files that define macro, data type, structure and functions are given in the summary Table at the end of this Tutorial.
Names for “errno” values (error numbers).
struct sockaddr; system prototypes and constants.
Network info lookup prototypes and structures.
struct sockaddr_in; byte ordering macros.
Utility function prototypes.
Ancillary Socket Topics
UDP versus TCP.
Controlling/managing socket characteristics.
get/setsockopt() - keepalive, reuse, nodelay.
fcntl() - async signals, blocking.
ioctl() - file, socket, routing, interface options.
Blocking versus Non-blocking socket.
Signal based socket programming (SIGIO).
Implementation specific functions.
Socket header files
Programs that use the socket functions must include one or more header files that contain information that is needed by the functions, such as:
Data type definitions.
The following Table is a summary of the header files used in conjunction with the socket APIs. However, different kernel version will have slightly different header files and the path as well. Please refer to the online Linux source code repository (linux cross reference - lxr) for the desired kernel version.
Header file name
Defines prototypes for those network library routines that convert Internet address and dotted-decimal notation, for example, inet_makeaddr().
Defines Internet name server macros and structures that are needed when the system uses the resolver routines.
Defines macros and variables for error reporting.
Defines prototypes, macros, variables, and structures for control-type functions, for example, fcntl().
Defines prototypes, macros, variables, and the ifreq and ifconf structures that are associated with ioctl() requests that affect interfaces.
Defines prototypes, macros, variables, and the rtentry and rtconf structures that are associated with ioctl() requests that affect routing entries.
Contains data definitions for the network library routines. Defines the following structures:
Defines prototypes, macros, variables, and the sockaddr_in structure to use with Internet domain sockets.
Defines macros, variables, and structures that are associated with setting IP options.
Defines macros, variables, and structures that are associated with the Internet Control Message Protocol (ICMP).
Defines macros, variables, and structures that are associated with setting TCP options.
Defines IPX packet header. May be needed in AF_NS socket applications.
Defines ioctl structures for IPX ioctl() requests. May be needed in AF_NS socket applications.
Defines AF_NS socket structures and options. You must include this file in AF_NS socket applications.
Defines SPX packet header. May be needed in AF_NS socket applications.
Defines sockaddr_tel structure and related structures and macros. You must include this file in AF_TELEPHONY socket applications.
Contains macros and structures that are used by the resolver routines.
Defines Secure Sockets Layer (SSL) prototypes, macros, variables, and the following structures:
Defines prototypes, macros, variables, and structures for I/O control-type functions, for example, ioctl().
Defines some limits to system fields, in addition to miscellaneous macros and prototypes.
Defines additional macros, types, structures, and functions that are used by signal routines.
Defines socket prototypes, macros, variables, and the following structures:
You must include this file in all socket applications.
Defines prototypes, macros, variables, and structures that are associated with time functions.
Defines various data types. Also includes prototypes, macros, variables, and structures that are associated with the select() function. You must include this file in all socket applications.
Defines prototypes, macros, variables, and structures that are associated with I/O functions.
Defines prototypes, macros, variables, and the sockaddr_un structure to use with UNIX domain sockets.
Contains macros and structures that are defined by the integrated file system. Needed when the system uses the read() and write() system functions.
Table 11: Header files for Linux sockets APIs
Continue on next Module…More in-depth discussion about TCP/IP suite is given in Advanced TCP/IP Socket programming.
Further reading and digging: