Sunday 29 January 2012

Server side socket tutorial ..made simple and easy !!!

Look into the client side first


In the server side the operation is no different but it involves certain other stuff which should be taken care of
We begin ,yes with the creation of socket

sid= socket(AF_INET, SOCK_STREAM, 0);

but before proceeding lets look at some more of the program
 
struct sockaddr_in saddr, caddr;

this creates a structure some thing like a drawer where each entity has its place and also different type can be stored something like you can keep books and clothes in different section of the drawer so that you can later access them pretty easily..structure does just that
This structures are defined beforehand and we need not worry at all

saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=htonl(INADDR_ANY);
    saddr.sin_port=htons(5122);

The 1st line just mentions the type of address format,and INADDR_ANY is a way of obtaining the ip address of the hostmachine in which the server runs,so if you use it in your machine ,you should get your ip address.
And the third one mentions the port number ..we randomly select 5122.You can go ahead and take what you like 22253 or 11489 or 86542 etc

once the socket is in place we need to bind it to the address which we have worked so far
we do so by :  bind(sfd, (struct sockaddr_in *)&saddr, sizeof(saddr));

now this socket represents the address and this address leads to a service because we have a port number as well in the address..

The server is ready to listen to connection from the clients we can ask the server to listen to client requests by using :  listen(sid, 5);
Please observe the socket here is represented by the id sid and the 5 indicates the queue length which can store the requests or if more than 1 request to the server occur simultaneously then a queue of request can be maintained.
Now we have dedicated this socket as a connection listener all it does is look out for connection requests something like a receptionist ,a pretty receptionist if i might add !

The server can accept the connection by :
cid=accept(sid, (struct sockaddr *)&caddr, &len);

Here actually a new socket is created so we don't disturb the receptionist who can always look for client request,with this new socket we can directly communicate with the client.The caddr stuff will give out the client address and the server need not know the client existence before this,makes sense eh!

then with that we can use read write operation and life becomes simpler.
THE END

Hold on! what will happen if multiple clients request for the same service in the server ?
We have seen the use of a queue in the listen ,but its only for listening and that too maximum queue length is 5.So our receptionist can handle 5 one after the other at a given time.
So all these people around the world use google and facebook ,how is it possible ?
well we use parallel processing we can use fork() which is done here to create a new virtual server something like this: The server sees more clients are needed their service so it clones itself and each of the clones will handle a single client
Problem solved!

So in short in server side

1.make a socket
2.bind it with the server ip address and a port number all the client should know this address to access the server
3.use this to listen to requests
4.for each request create a server clone and use a different socket to communicate with the client
5.use the read ,write to talk


Thats about it!

Socket Tutorial ..The easy way

The socket will involve few basic steps which allows you to connect to any server in the world wide web.Or service any client in the WWW.
The socket establish connection between two processes ,processes are nothing but programs and in this case what we are attempting is to connect one program say your browser request to another, the server side one..then you would be a client and a search program running on a google server would be the server side program.

check this out Programs

OK we will begin with the client side.
The client should know the server address which would be the IP address or the internet address also a single server may have multiple services similar to a street with many houses.To identify these services we have what is called a port number ..well actually port here is just a software entity.Which is used to refer to a service such as google translate or google docs etc.

To begin the client creates a socket by using the function socket(),the socket takes in certain arguments which indicate the type of address because ,out there in the real world there exist different address formats ip version 4,ip version 6 ,appletalk and so on.

so you got to mention which address format would the server client have,in our case ipv4 would do fine,the second argument is the type of socket,There exist two types

stream socket : The data transaction is in terms of a stream of characters

datagram socket: The data transaction here is in terms of chunks as though a
 entire segment of message is transmitted at one go.

Here we will use stream socket,and for the third argument it takes in the protocol or the rules which should be followed for traveling in the network and here we set it 0 and allow the operating system to choose it for us

sockid = socket(AF_INET, SOCK_STREAM, 0);


AF_INET : ipv4
sockstream: we discussed right
0:OS is looking after this

The second thing the client does once the socket is created is to connect it to the server which we need,for which the client should know the address of the server

connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr))

look we are using the sockid which is termed the file descriptor which is something like the id to a socket ,allowing us to have as many sockets in a program as we wish.
Now don't get scared by the 2nd argument we wont go deep into it ..Its just a pointer to a data entity  which contains all relevant information regarding the server which we desire to connect.
But how do the client know which server it needs to connect ?

server = gethostbyname(argv[1]);

we are passing the same as argument it may be an IP address or hostname some thing like mit.edu (this is just an example) would be fine.
Also we need to specify the port id with which the connection is to be made,

portno = atoi(argv[2]);

the 2nd argument of our program will do it for us

once the connection is made voila!! we can talk with the server using the READ and WRITE

read(sockfd,buffer,255);
write(sockfd,buffer,strlen(buffer));

Thats it!! we are done
so in short

1.make a socket socket()
2.connect with server for which IP address and port number is needed
3.use read and write

now to server side Server awaits your presence

Ahhhhhh save us all...Its the Zombie Process !

When a parent process does not use wait() which will allow the parent to wait until its child has finished execution,or use signal(SIGCHLD, SIG_IGN); ,the sigchld signal indicates the death or for that matter the completion of a child process and it allows the parent to know the same, the usage of the above function with sig_ign as the second argument indicates to ignore the death of the child.
However if wait or the signal functions are not used then the child even after completion will have an entry in the process table..though all its resource are deallocated ,and how cool can it get (seriously !) it can't be "killed" by a kill() command..
You can see zombies if any by using the ps command in the terminal and observing the Z at stat column.

Socket programming ,A server with multiple clients;Guest starring "fork()"

A network socket is an endpoint of an inter-process communication flow
across a computer network. Today, most communication between computers
is based on the Internet Protocol; therefore most network sockets are Internet
sockets.
A socket address is the combination of an IP address and a port number,
much like one end of a telephone connection is the combination of a phone
number and a particular extension. Based on this address, internet sockets deliver incoming data packets to the appropriate application process or
thread.
Computer processes that provide application services are called servers, and
create sockets on start up that are in listening state. These sockets are waiting for initiatives from client programs.
Thus the client will initiate a connection with server by means of socket and
communicates by means of read,write instruction.The server on the other
hand will perform listening and binding operation to accept the connection
from the client.

SERVER


CLIENT
Program which can allow server to service multiple clients using fork() ,here a simple arithmetic operation entered by the user as a client will be computed at the server end and the result is displayed back to the client.It allows you to setup communication between different systems in a LAN or the internet itself.



client program:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");
    printf("Please enter the operation: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;
}
//ends

Server program

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include<math.h>
#include<stdlib.h>

int main()
{
    int sfd, cfd,i=0,a1,a2,b,j=0;
    socklen_t len;
char a[100],b1[50];
    char ch[255],buff[INET_ADDRSTRLEN],c;
    struct sockaddr_in saddr, caddr;

    sfd= socket(AF_INET, SOCK_STREAM, 0);

    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=htonl(INADDR_ANY);
    saddr.sin_port=htons(1205);

    bind(sfd, (struct sockaddr *)&saddr, sizeof(saddr));

    listen(sfd, 5);
    signal(SIGCHLD, SIG_IGN);

    while(1) {
        printf("Server waiting\n");
        len=sizeof(caddr);
        cfd=accept(sfd, (struct sockaddr *)&caddr, &len);

        if( fork() == 0) {
            printf("Child Server Created Handling connection with %s\n",
                inet_ntop(AF_INET, &caddr.sin_addr, buff, sizeof(buff)));

            close(sfd);

          if(read(cfd, ch, 255)<0) perror("read");

         
   
memset(a, 0, 100);
// parsing
while((ch[i]!='-') && (ch[i]!='+') && (ch[i]!='*') && (ch[i]!='/'))
{

a[i]=ch[i];
i++;
}
 a1 = atoi(a);
c=ch[i];i++;

memset(a, 0, 100);
while(ch[i] != '\0')
{

a[j]=ch[i];
i++;
j++;
}

memset(ch,0,255);
a2 = atoi(a);
//parsing ends here
switch(c)
{case '+': b =a1+a2;
break;
case '-':b = a1 - a2;
break;
case '*': b= a1 * a2;
break;
case '/':
if(a2 != 0)
b= a1 / a2;
else
b=0;

}

sprintf(ch,"%d",b);


                if(write(cfd, ch, sizeof(ch))<0) perror("write");

            
            close(cfd);
            return 0;

        }

        close(cfd);
    }
}

//ends



How to run ?

compile the above programs and execute the server first..note the server uses a port no of 1205..you need to pass this for the client program in command line

for linux
executing server program

>gcc filename.c -o s
>./s

execute client
>gcc filename1.c -o c
>./c localhost 1205


instead of localhost you can supply ip address.


Tutorial awaits

and yeah it was a lousy assignment of mine...