Networking and Socket programming Tutorial on C

This article is welcome for the programmer with following requirement.

network5

Before start learning socket programming make sure you already have certain basic knowledge

to network such as understand what is IP address, TCP, UDP.

Before we started our tutorial, keep it mind that following tutorial is only worked on LINUX OS environment. If you are using window, I have to apologize to you because window have it own socket programming and it is different from Linux even though the connection concept is same.

Well, first copy and paste the following code and run it on server and client respectively.

Both code can be done on same computer.

There is always easy to be understand after getting the things works.

Socket-server.c

 

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
 
int main(void)
{
  int listenfd = 0,connfd = 0;
  
  struct sockaddr_in serv_addr;
 
  char sendBuff[1025];  
  int numrv;  
 
  listenfd = socket(AF_INET, SOCK_STREAM, 0);
  printf("socket retrieve success\n");
  
  memset(&amp;serv_addr, '0', sizeof(serv_addr));
  memset(sendBuff, '0', sizeof(sendBuff));
      
  serv_addr.sin_family = AF_INET;    
  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
  serv_addr.sin_port = htons(5000);    
 
  bind(listenfd, (struct sockaddr*)&amp;serv_addr,sizeof(serv_addr));
  
  if(listen(listenfd, 10) == -1){
      printf("Failed to listen\n");
      return -1;
  }
  while(1)
    {
      
      connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL); // accept awaiting request
  
      strcpy(sendBuff, "Message from server");
      write(connfd, sendBuff, strlen(sendBuff));
 
      close(connfd);    
      sleep(1);
    }
 
 
  return 0;
}

Socket-client.c

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
 
int main(void)
{
  int sockfd = 0,n = 0;
  char recvBuff[1024];
  struct sockaddr_in serv_addr;
 
  memset(recvBuff, '0' ,sizeof(recvBuff));
  if((sockfd = socket(AF_INET, SOCK_STREAM, 0))&lt; 0)
    {
      printf("\n Error : Could not create socket \n");
      return 1;
    }
 
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(5000);
  serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
  if(connect(sockfd, (struct sockaddr *)&amp;serv_addr, sizeof(serv_addr))&lt;0)
    {
      printf("\n Error : Connect Failed \n");
      return 1;
    }
 
  while((n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) &gt; 0)
    {
      recvBuff[n] = 0;
      if(fputs(recvBuff, stdout) == EOF)
    {
      printf("\n Error : Fputs error");
    }
      printf("\n");
    }
 
  if( n &lt; 0)
    {
      printf("\n Read Error \n");
    }
 
 
  return 0;
}

After debug both source file, run Socket-server.out, then run Socket-client. Attention here, never mess up with the order of execute Socket-server.out and Socket-client. Socket-server must be executed first then execute Socket-client.out and never tried to break Socket-server forever loop. It means, you need to open two terminal to run each of the output.

When you execute Socket-cli, I guess you will get the result as following.

network2

network1

If you see the message above. Congratulations, you have success with your first step to networking programming. Otherwise, do some checking on your develop environment or tried to do some simple code for instance hello world.

WHY both server and client is happened on same computer?

The answer is server and client both are software but not hardware. It means what happening on the top is there are two different software are executed. Be more precise, server and client are two different process with different work. If you are experienced with constructing server you might find out that server can be built on home computer by install server OS. It is because, server is a kind of software.

Understand what is socket

Imagine socket as a seaport that allow the ship to unload and gather their shipping, where socket is the place where computer gather and put the data into internet.

network3

Configure Socket

Things that need to be initialized are listed as following

  1. Using TCP or UDP
  2. Additional protocol
  3. Permit the incoming IP address
  4. Assign the port used

At the beginning, socket function need to be declared to get socket descriptor.

int socket(int domain, int type, int protocol);
Domain AF_UNIX – connect inside same machine

AF_INET – connect with different machine

Type SOCK_STREAM – TCP connection

SOCK_DGRAM – UDP connection

Protocol Define here when there is any additional protocol. Otherwise, define it as 0

Next, decide which struct needs to be used based on what domain used on above.

AF_UNIX
AF_INET
struct sockaddr_un

{

sa_family_t sun_family;

char sun_path[];

}

 

struct sockaddr_in

{

short int sin_family;

int sin_port;

struct in_addr sin_addr;

};

Use struct sockaddr_un if you are using AF_UNIX on your domain.

It is required to include

Use struct sockaddr_in if you are using AF_INT on your domain.

On this article, I will explain sockadd_in that showed on the code above.

serv_addr.sin_family = AF_INET; Define the domain used
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); Permit any incoming IP address by declare INADDR_ANY
serv_addr.sin_port = htons(5000); Declare port 5000 to be used.

Based on example above, server is using port 5000. You can check it by following command

sudo netstat -ntlp

Then, you will see following list

network6

Inside red bracket, you will found 0.0.0.0:5000 and Socket-server, it means port 5000 is used and listen to any valid incoming address.

On client side, client should also listen to port 5000 as server is using port 5000.  Client side script must also declared in this way, serv_addr.sin_port = htons(5000).

The flow chart below shows the interaction between client and server. The flow chart might looks complicated but make sure you don’t lost your patient due to the following flow chart. Because every process on the flow chart is needed and it acts a very important roles on network connection.

network4

After all setup on struct sockaddr_in is done, declare bind function. As flow chart, bind function must be declared on both server and client.

bind function

server_socket & client_socket Put socket description retrieved on the top
address Put struct sockaddr_in into it as domain is AF_INET. If your domain is AF_UNIX, tried put struct sockaddr_un here.
address_len Put the length of the address

Server and client will start interact with each other after the bind function and it is the most important session. From what flow chart shows, listen, accept, connect, three function play a very important roles.

Imagine that server looks like an ATM, and only one person can be used the ATM. So, what happen if there is 2 or more people come at one time? The answer is simple, lining up and wait the front people finished using with ATM. It is exactly same as what happening in server.

Listen function acts as waiting room, asking the traffic wait on the waiting room. Accept function acts as person who asking the traffic waiting inside the waiting room to be ready for the meeting between server. Last, connect function acts as the person who want to carry out some work with server.

listen function

server_socket Put socket description retrieved on the top
backlog Define the maximum of awaiting request

accept function

server_socket Put socket description retrieved on the top
client_address Put null here if there is no any special request to specify address.
address_len Put null here if second parameter is null
return Return information of client socket description. Use it for interact between client and server.

connect function

client_socket Put socket description retrieved on the top
address Put the struct sockaddr defined on the top
address_len Put the length of the address

Finally, after the request accepted. What should server and client do is send and read data. It is the most simple part in whole of this article. read function used to read the buffer data and write function used to send the data. That’s all.

read function

socket_description Put server or client socket description depend on reading data from server or client
read buffer Content of the data retrieved
read buffer length Length of the output string

write function

socket_description Put server or client socket description depend on sending data to server or client
write buffer Data to be send
write buffer length Length of the output string

 

Personal Comment

This article was publish on 2013/5/1 and I was still new to networking programming on this period. Maybe there is some point that I am not make clear enough, I have tried all of my best to present all my knowledge to this article. Hope you can get the good basic beginning over here. Thank you.

Square Root algorithm for C

Introduction

For those who are looking for how square root algorithm is working and “YES !, Welcome to my blog”, but for those who are simply looking for performing square root your programming and I have to tell you, what you have to do is do some google searching on “math.h” header file to look for square root function that prepared inside it.
Well, let’s begin our lesson “How square root algorithm is working on c”
It’s not very difficult once you have understand how following equation is calculated
eq2

Left hand side of the diagram shows the square root of 152.2756 and right hand side shows the square root of 2.
For those who have understand how this calculation is been done, please skip to the code as I am going to explain the how to solve this equation.

Basic Principle of Square Root

Based on the question given above, we understand that square root of 152.2756 is 12.34 and the square root of 2 is 1.4142. If you do not believe, try calculator to find the answer.
Suppose we are finding the square root of 2 and the answer is 1.4142. We can expressed it such that

clip_image002[6]

If we expressed it to algebra expression as following.
clip_image002[8]
Suppose a is continue for n times, it can be expressed as following
ex3

Why I am treating it continue as n times but not 5 times? Because we cannot ensure that all positive number will give us a 5 digits answer after square root it. So we have to suppose there are n digits after square root.
Right-hand-side term can be expanded as following
ex4

From the equation above, we can understand square root equation can be solved by following equation.
ex5

The most important rule of this equation is we pick a number from 1,2,3,4,5,6,7,8,9 and multiple it with 10^m, where m = Integer (exp. 3,2,1,0,-1,-2,-3,…) and substitute into  clip_image002[12]that must be smaller then the number we are going to minus or equal to it. It’s the most difficult part on square-root equation so lets understand it by solving square root of 2.

So, from the solution above, we understand that
eq8
And we sum up all the value, we get the answer 1.414 approximate to 1.4142

Algorithm

Based on the method above, what kind of works should we applied on algorithm as following

  • Create equation
  • Create function of power of ten
  • Find suitable number that bigger then 0 for variable a from loop
  • Find suitable number that smaller then 0 but positive for variable a from loop
  • Sum all variable a and return it as double

First, we are going to create the equation as we mentioned above
ex5
We can expressed it as code as following


(( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i))

where rst and j is declared as double and i is int. powerOfTen is a function that return a value of i times multiple of 10.

It’s code of function powerOfTen

double powerOfTen(int num){
     double rst = 1.0;
     if(num >= 0){
          for(int i = 0; i < num ; i++){
               rst *= 10.0;
          }
     }else{
          for(int i = 0; i < (0 - num ); i++){
               rst *= 0.1;
          }
     }

     return rst;
}

We have to judge that variable a must be smaller then upper number. It’s how it looks like

if(z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)

where z  is declared as double and treat as upper number.

There are two loops, one loop for finding the suitable number from 10000,1000,100,10… and another one loop for find suitable number from 1,2,3,4,5…

for(i = max ; i > 0 ; i--){

     // value must be bigger then 0
     if(z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
     {
          while( z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
          {
               j++;
               if(j >= 10) break;
          }

          j--; //correct the extra value by minus one to j

          z -= (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)); //find value of z

          rst += j * powerOfTen(i);     // find sum of a

          j = 1.0;

     }
}

Same loop as above but this times we are going to find the decimal number.

for(i = 0 ; i >= 0 - max ; i--)
{

     if(z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
     {
          while( z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
          {
               j++;
               if(j >= 10) break;                    
          }

          j--;
          z -= (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)); //find value of z
          rst += j * powerOfTen(i);     // find sum of a               
          j = 1.0;
          
     }
}

This is how the whole squareRoot algorithm looks like

double squareRoot(double a)
{
     /*

          find more detail of this method on wiki methods_of_computing_square_roots
          *** Babylonian method cannot get exact zero but approximately value of the square_root

     */


     double z = a;     
     double rst = 0.0;
     int max = 8;     // to define maximum digit 
     int i;
     double j = 1.0;
     for(i = max ; i > 0 ; i--){
          // value must be bigger then 0
          if(z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
          {
               while( z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
               {
                    j++;
                    if(j >= 10) break;
                    
               }
               j--; //correct the extra value by minus one to j
               z -= (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)); //find value of z

               rst += j * powerOfTen(i);     // find sum of a
               
               j = 1.0;
          

          }          

     }

     for(i = 0 ; i >= 0 - max ; i--){
          if(z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
          {
               while( z - (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)) >= 0)
               {
                    j++;
                    if(j >= 10) break;                    
               }
               j--;
               z -= (( 2 * rst ) + ( j * powerOfTen(i)))*( j * powerOfTen(i)); //find value of z

               rst += j * powerOfTen(i);     // find sum of a               
               j = 1.0;
          }
     }
     // find the number on each digit
     return rst;
}

Reference

I am referring to this wiki website. For more details, please refer on this website. Thank you.