|Winsock & .NET |Winsock | < TCP/IP Client Server Model | Linux Socket Index | More TCP/IP Programming Interfaces (APIs) > |


 

 

 

 

 

NETWORK PROGRAMMING

LINUX SOCKET PART 3: MORE ON APIs

 

 

 

 

 

Menu

 

Network Story 1

Network Story 2

Network Story 3

Network Story 4

Network Story 5

Network Story 6

Socket Example 1

Socket Example 2

Socket Example 3

Socket Example 4

Socket Example 5

Socket Example 6

Socket Example 7

Advanced TCP/IP 1

Advanced TCP/IP 2

Advanced TCP/IP 3

Advanced TCP/IP 4

Advanced TCP/IP 5

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.

 

Generic Socket Address Structure

 

Host IP Addresses

  • Each computer on the Internet has one or more Internet addresses, numbers which identify that computer among all those on the Internet.

  • Users typically write numeric host addresses as sequences of four numbers, separated by periods, as in 128.54.46.100.

  • Each computer also has one or more host names, which are strings of words separated by periods, as in www.google.com.

  • Programs that let the user specify a host typically accept both numeric addresses and host names.

  • But the program needs a numeric address to open a connection; to use a host name; you must convert it to the numeric address it stands for.

Internet Host Addresses – Abstract Host Address

  • Each computer on the Internet has one or more Internet addresses, numbers which identify that computer among all those on the Internet.

  • An Internet host address is a number containing four bytes of data.  These are divided into two parts, a network number and a local network address number within that network.

  • The network number consists of the first one, two or three bytes; the rest of the bytes are the local address.

  • Network numbers are registered with the Network Information Center (NIC), and are divided into three classes as discussed before: class A, B, and C for the IPv4.  The local network address numbers of individual machines are registered with the administrator of the particular network.

  • Since a single machine can be a member of multiple networks, it can have multiple Internet host addresses.

  • However, there is never supposed to be more than one machine with the same host address.

  • There are four forms of the standard numbers-and-dots notation for Internet addresses as discussed before:

  1. a.b.c.d - This specifies all four bytes of the address individually.

  2. a.b.c - The last part of the address, c, is interpreted as a 2-byte quantity.  This is useful for specifying host addresses in a Class B network with network address number a.b.

  3. a.b - The last part of the address, c, is interpreted as a 3-byte quantity.  This is useful for specifying host addresses in a Class A network with network address number a.

  4. a - If only one part is given, this corresponds directly to the host address number.

  • Within each part of the address, the usual C conventions for specifying the radix apply.  In other words, a leading '0x' or '0X' implies hexadecimal radix; a leading '0' implies octal; and otherwise decimal radix is assumed.

Host Address Data Type - Data type for a host number.

  • Internet host addresses are represented in some contexts as integers (type unsigned long int).

  • In other contexts, the integer is packaged inside a structure of type struct in_addr.  It would be better if the usages were made consistent, but it is not hard to extract the integer from the structure or put the integer into a structure.

  • The following basic definitions for Internet addresses appear in the header file 'in.h'.

struct in_addr

  • This data type is used in certain contexts to contain an Internet host address.  It has just one field, named s_addr, which records the host address number as an unsigned long int.

unsigned long int INADDR_LOOPBACK

unsigned long int INADDR_ANY

unsigned long int INADDR_BROADCAST

unsigned long int INADDR_NONE

Host Address Functions - Functions to operate on them

int inet_aton(const char *name, struct in_addr *addr)

unsigned long int inet_addr(const char *name)

unsigned long int inet_network(const char *name)

char * inet_ntoa(struct in_addr addr)

struct in_addr inet_makeaddr(int net, int local)

int inet_lnaof(struct in_addr addr)

Function int inet_netof(struct in_addr addr)

Host Names - Translating host names to host IP numbers

  • Besides the standard numbers-and-dots notation for Internet addresses, you can also refer to a host by a symbolic name.

  • The advantage of a symbolic name is that it is usually easier to remember.  For example, the machine with Internet address '128.52.46.32' is also known as 'testo.google.com'; and other machines in the 'google.com' domain can refer to it simply as 'testo'.

  • Internally, the system uses a database to keep track of the mapping between host names and host numbers.

  • This database is usually either the file '/etc/hosts' or an equivalent provided by a name/DNS server.  The functions and other symbols for accessing this database are declared in 'netdb.h'. They are BSD features, defined unconditionally if you include 'netdb.h'.

  • The IP address to name and vice versa is called name resolution.  It is done by Domain Name Service.  Other than the hosts file, in Windows platform it is called DNS (Domain Name Service) and other Microsoft specifics may use WINS or lmhost file.  Keep in mind that the general term actually Domain Name System also has DNS acronym.  In UNIX it is done by BIND.

  • The complete process or steps taken for name resolution quite complex but Windows normally use DNS service and UNIX/Linux normally use BIND.

Data Type struct hostent

Data Type

Description

char *h_name

This is the ''official'' name of the host.

char **h_aliases

These are alternative names for the host, represented as a null-terminated vector of strings.

int h_addrtype

This is the host address type; in practice, its value is always AF_INET.  In principle other kinds of addresses could be represented in the data base as well as Internet addresses; if this were done, you might find a value in this field other than AF_INET.

int h_length

This is the length, in bytes, of each address.

char **h_addr_list

This is the vector of addresses for the host.  Recall that the host might be connected to multiple networks and have different addresses on each one.  The vector is terminated by a null pointer.

char *h_addr

This is a synonym for h_addr_list[0]; in other words, it is the first host address.

 

Table 5

struct hostent * gethostbyname(const char *name)

struct hostent * gethostbyaddr(const char *addr, int length, int format)

extern  int   h_errno;

h_errno

Description

HOST_NOT_FOUND

No such host is known in the data base.

TRY_AGAIN

This condition happens when the name server could not be contacted. If you try again later, you may succeed then.

NO_RECOVERY

A non-recoverable error occurred.

NO_ADDRESS

The host database contains an entry for the name, but it doesn't have an associated Internet address.

 

Table 6

Function void sethostent(int stayopen)

Function struct hostent * gethostent()

Function void endhostent()

The API Details

struct sockaddr

struct sockaddr {
    u_char  sa_len;

    u_short sa_family;     // address family, AF_xxx

    char    sa_data[14];   // 14 bytes of protocol address

};
  1. The short integer that defines the address family (the value that is specified for address family on the socket() call).

  2. Fourteen bytes that are reserved to hold the address itself.

struct sockaddr_in

struct sockaddr_in {
    u_char  sin_len;

    u_short sin_family;        // Address family

    u_short sin_port;         // Port number

    struct  in_addr sin_addr;  // Internet or IP address

    char    sin_zero[8];      // Same size as struct sockaddr

};

Socket System Calls

 

socket()

NAME
       socket() - create an endpoint for communication
SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       int socket(int domain, int type, int protocol);

 

 

 

 

 

 

 

 

bind()

NAME
       bind() - bind a name to a socket
SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

[bodo@bakawali testsocket]$ cat test1.c

#include <string.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

#define MYPORT 3334

 

int main()

{

int sockfd; /* socket file descriptor */

struct sockaddr_in my_addr;

 

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

  perror("Server-socket() error lol!");

  exit(1);

}

else

  printf("Server-socket() sockfd is OK...\n");

 

/* host byte order */

my_addr.sin_family = AF_INET;

/* short, network byte order */

my_addr.sin_port = htons(MYPORT);

my_addr.sin_addr.s_addr = INADDR_ANY;

/* zero the rest of the struct */

memset(&(my_addr.sin_zero), 0, 8);

 

if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)

{

  perror("Server-bind() error lol!");

  exit(1);

}

else

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

 

/*....other codes....*/

 

return 0;

}

 

[bodo@bakawali testsocket]$ gcc test1.c -o test1

[bodo@bakawali testsocket]$ ./test1

Server-socket() sockfd is OK...

Server-bind() is OK...

/* choose an unused port at random */

my_addr.sin_port = 0;

/* use my IP address */

my_addr.sin_addr.s_addr = INADDR_ANY;

/* choose an unused port at random */

my_addr.sin_port = htons(0);

/* use my IP address */

my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

int yes = 1;

/* "Address already in use" error message */

if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)

{

  perror("setsockopt() error");

  exit(1);

}

else

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

connect()

NAME
       connect() - initiate a connection on a socket.
SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

[bodo@bakawali testsocket]$ cat test2.c

#include <unistd.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

#define DEST_IP "127.0.0.1"

#define DEST_PORT 80

 

int main(int argc, char *argv[ ])

{

int sockfd;

/* will hold the destination addr */

struct sockaddr_in dest_addr;

 

sockfd = socket(AF_INET, SOCK_STREAM, 0);

 

if(sockfd == -1)

{

  perror("Client-socket() error lol!");

  exit(1);

}

else

  printf("Client-socket() sockfd is OK...\n");

 

/* host byte order */

dest_addr.sin_family = AF_INET;

/* short, network byte order */

dest_addr.sin_port = htons(DEST_PORT);

dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);

 

/* zero the rest of the struct */

memset(&(dest_addr.sin_zero), 0, 8);

 

if(connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) == -1)

{

  perror("Client-connect() error lol");

  exit(1);

}

else

  printf("Client-connect() is OK...\n");

 

/*...other codes...*/

 

return 0;

}

 

[bodo@bakawali testsocket]$ gcc test2.c -o test2

[bodo@bakawali testsocket]$ ./test2

Client-socket() sockfd is OK...

Client-connect() error lol: Connection refused

Continue on next Module.....More in-depth discussion about TCP/IP suite is given inAdvanced TCP/IP tutorials.

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Check thebest selling C/C++, Networking, Linux and Open Source books at Amazon.com.

  2. Protocol sequence diagram examples.

  3. Another site for protocols information.

  4. RFCs.

  5. GCC, GDB and other related tools.

 

 

 

 


|Winsock & .NET |Winsock | < TCP/IP Client Server Model | Linux Socket Index | More TCP/IP Programming Interfaces (APIs) > |