Sunday, August 7, 2011

The purpose of the bind function in socket


When your socket is created by the socket(2) function, it is nameless. You saw in my first post1, "Introducing Sockets" that sockets could be used without addresses when the socketpair(2)
function was illustrated. However, this worked only because those sockets were created this way, within one Linux kernel. This cannot be done for sockets that must be joined between two different hosts.
A nameless socket is otherwise difficult to use. No one can send information to your nameless socket, because it is like a telephone without a telephone number. Consequently, programmers must bind a name to the socket to make it reachable by someone else. This is like assigning a telephone number to a new telephone so that it can be called. The bind(2) function call permits you to assign an address to a socket in the same manner.

A "name" in the context of this chapter has nothing to do with hostnames such as sunsite.unc.edu.
The word "name" is often used when discussing the bind(2) function, and it refers to the address of the socket. The address, after all, is a name of sorts. To avoid confusion, however, the term address will be favored in this chapter.

Using the bind(2) Function

The purpose of the bind(2) function is to assign a socket address to a nameless socket. The function synopsis is given as follows:

#include <sys/types.h>
#include <sys/socket.h>

int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

The function accepts the following three input arguments:
  1. The socket sockfd file descriptor that was returned by a prior socket(2) call.
  2. The address my_addr to assign to the socket.
  3. The length of the address my_addr in bytes (argument addrlen).

The function, if it is successful, returns the value zero. Otherwise, the value -1 is returned and the variable errno has the reason for the failure posted to it.

NOTE
The socket provided to bind(2) must be presently nameless (without an address). You cannot rebind a socket to a new address.

The address argument must be a pointer to the address structure. You will note that the generic address type used is the sockaddr structure type. This means that you will need to apply a C
language cast operator to satisfy the compiler that you have passed the correct pointer type. Listing below shows a program that calls upon bind(2) to establish an Internet address. Note the use of the inet_aton(3) and bind(2) function calls.

/* af_inet.c:
 * Demonstrating the bind(2) function
 * by establishing a Specific AF_INET
 * Socket Address:
 */
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>


/*
 * This function reports the error and
 * exits back to the shell:
 */
 static void displayError(const char *on_what) {
    perror(on_what);
    exit(1);
 }

 int  main(int argc, char **argv, char **envp) {
    int z;            //Status return code 
    int sck_inet;     // Socket 
    struct sockaddr_in adr_inet; // AF_INET
    int len_inet;     // length
/* 
 * Create an IPv4 Internet Socket 
 */
    sck_inet = socket(AF_INET,SOCK_STREAM,0);

    if ( sck_inet == -1 ) {
       displayError("socket()");
     }
/* 
 * Create an AF_INET address 
 */
    memset(&adr_inet, 0, sizeof adr_inet);

    adr_inet.sin_family = AF_INET;
    adr_inet.sin_port = htons(9000);

    inet_aton ("127.0.0.24",&adr_inet.sin_addr);

    len_inet = sizeof adr_inet;
/* 
 * Now bind the address to the socket 
 */
    z = bind(sck_inet, (struct sockaddr *)&adr_inet, len_inet);

    if ( z == -1 ) {
       displayError("bind()");
    }
/* 
 * Display all of our bound sockets 
 */
    system("netstat -pa --tcp 2>/dev/null | sed -n '1,/^Proto/p;/bind/p'");

    close(sck_inet);
    return 0;
 }
NOTE
If the netstat(1) command on your system does not support the options used in above program, substitute the following call if you have the lsofcommand installed:
system("lsof -i tcp | sed -n '1p;/bind/p'");




No comments:

Post a Comment