Tuesday, 16 July 2013

Finite State Machine Implementation in C for Real Time Applications

 
Dear Reader,

  In this post, you can find the Finite state Machine Implementation in C useful for real time applications.

Please refer my earlier blog post "Simple finite state Machine for Beginners" to get basics of FSM.

The current implementation of FSM contains three states as STATE_1, STATE_2 and STATE_3 and three events as EVENT_1, EVENT_2, EVENT_3.

FSM works based on the events which are been triggered during at point of time. 

e.g:
Case 1 : If the FSM is in STATE_1 and FSM receives an EVENT_2 then it shall call the respective action function and change it next state as  STATE_2.

 Case 2: If the FSM is in STATE_2 and FSM receives an EVENT_2 then it remains in the same state as STATE_2.
 
 

 Finite State Machine Implementation In C
 ================================

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/* This program Implements the Finite state Machine which contains
 * 3 states as STATE_1, STATE_2, STATE_3 and 3 EVENTS
 * EVENT_1, EVENT_2, EVENT_3 as depicted below

 STATES/EVENTS  | EVENT_1 | EVENT_2 | EVENT_3 | EVENT_4  
 ======================================================
 STATE_1        |
 ----------------
 STATE_2        |
 ----------------
 STATE_3        |
 ----------------
*/

/*
 * Declare states
 */
typedef enum states
{
   INVALID_STATE = 0,
   STATE_1,
   STATE_2,
   STATE_3,
   MAX_STATES
}FSMStates;

/*
 * Declare Events
 */
typedef enum events
{
   INVALID_EVENT = 0,
   EVENT_1,
   EVENT_2,
   EVENT_3,
   MAX_EVENTS
}FSMEvents;

/* Call back Function */
typedef void (*FSMActionFunc)(void *data1);


/* =========================
 * Declaration of FSMStruct
 * =========================
 * FSM Struct should contain
 * ACTION function and Next State
 */
typedef struct FSM
{
   /* Action Function */
   FSMActionFunc  actionFunc;
   /* Next State */
   FSMStates      nextState;
}FSMStruct;



/* Declare FSMStruct Variable */
FSMStruct FSMArray[MAX_STATES][MAX_EVENTS];

/* The Handle Functions are declared Here */
unsigned char currentState;

void processFSMEvent(unsigned int event);
void handle_FSM_EVENT_1(void *data1);
void handle_FSM_EVENT_2(void *data1);
void handle_FSM_EVENT_3(void *data1);

void  initialiseFSM(void)
{
   /* Memset to FSMArray to Zero */
   memset(FSMArray, 0x00,  sizeof(FSMStruct));

   /* Intial State */
   currentState = STATE_1;

   /* STATE_1 Intialisation */
   FSMArray[STATE_1][EVENT_1].actionFunc = handle_FSM_EVENT_1;
   FSMArray[STATE_1][EVENT_1].nextState  = STATE_1;

   FSMArray[STATE_1][EVENT_2].actionFunc = handle_FSM_EVENT_2;
   FSMArray[STATE_1][EVENT_2].nextState  = STATE_2;
 
   FSMArray[STATE_1][EVENT_3].actionFunc = handle_FSM_EVENT_3;
   FSMArray[STATE_1][EVENT_3].nextState  = STATE_3;

   /* STATE 2 */
   FSMArray[STATE_2][EVENT_1].actionFunc = handle_FSM_EVENT_1;
   FSMArray[STATE_2][EVENT_1].nextState  = STATE_1;
  
   FSMArray[STATE_2][EVENT_2].actionFunc = handle_FSM_EVENT_2;
   FSMArray[STATE_2][EVENT_2].nextState  = STATE_2;

   FSMArray[STATE_2][EVENT_3].actionFunc = handle_FSM_EVENT_3;
   FSMArray[STATE_2][EVENT_3].nextState  = STATE_3;
  
   /* STATE 3 */
   FSMArray[STATE_3][EVENT_1].actionFunc = handle_FSM_EVENT_1;
   FSMArray[STATE_3][EVENT_1].nextState  = STATE_1;

   FSMArray[STATE_3][EVENT_2].actionFunc = handle_FSM_EVENT_2;
   FSMArray[STATE_3][EVENT_2].nextState  = STATE_2;
  
   FSMArray[STATE_3][EVENT_3].actionFunc = handle_FSM_EVENT_3;
   FSMArray[STATE_3][EVENT_3].nextState  = STATE_3;
}

/*
 * Handle Event-1  Fn
 */
void handle_FSM_EVENT_1(void *data1)
{
   char *buffer = (char *)data1;
   printf("--------------------------------------------------------------\n");
   printf("OUTPUT OF FSM :In function handle_FSM_EVENT_1 : %s\n", buffer);
   printf("--------------------------------------------------------------\n");
}
/*
 * Handle Event-2  Fn
 */
void handle_FSM_EVENT_2(void *data1)
{
   char *buffer = (char *)data1;
   printf("--------------------------------------------------------------\n");
   printf("OUTPUT OF FSM : In function handle_FSM_EVENT_2 : %s\n", buffer);
   printf("--------------------------------------------------------------\n");
}
/*
 * Handle Event-3  Fn
 */
void handle_FSM_EVENT_3(void *data1)
{
   char *buffer = (char *)data1;

   printf("--------------------------------------------------------------\n");
   printf("OUTPUT OF FSM : In function handle_FSM_EVENT_3 : %s\n", buffer);
   printf("--------------------------------------------------------------\n");
}
/*
 * processFSMEvent()
 */
void processFSMEvent(unsigned int event)
{
  char data1[20];

  if ((event > INVALID_EVENT) && (event < MAX_EVENTS)) 
   {
     if(event == EVENT_1)
     {
       strcpy(data1, "EVENT_1 Data\n");
     }
     else if(event == EVENT_2)
     {
       strcpy(data1, "EVENT_2 Data\n");
     }
     else
     {
       strcpy(data1, "EVENT_3 Data\n");
     }
    
     /* Call the Respective Action Function */
     FSMArray[currentState][event].actionFunc(data1);


     /* Set the Current State */
     currentState =  FSMArray[currentState][event].nextState;
   }
  else
   {
      printf(" Event is Invalid \n");
   }
}
/*
 * Main fn
 */
int main()
{
   unsigned int event; char ch;

   /* Initialise FSM */
   initialiseFSM();

  do
   {     
      printf("Enter the Event(1-3) To be Trigger in FSM STATE Machine \n");
      scanf("%d", &event);

      /* Process FSM Events */
      processFSMEvent(event);

      printf("Do You Want To Run STATE MACHINE Further ....\n");
      printf("For exit enter 100-> Other wise to Continue Enter any  Number\n");
      scanf("%d", &ch);

   }while(ch!= 100);
}

















Thursday, 11 July 2013

BITMAP Implementation in C

Dear Reader,

    In this post, i would like to bring you about BIT MAP and its implementation in C used for real time applications

What is BIT MAP?
   Bit Maps are also called as " BIT Array".
   Bit array means that store bits.

Why  BIT MAPS are required?
   Using Bit Array, applications achieve bit-level parallelism in hardware to perform operations quickly.

Some more Info..

Each bit array is mapped to some domain, the bit values can be interpreted as

1. Dark/Light  2. Absent/Present   3. Locked/Unlocked    4. Valid/Invalid

In other words, there are only two possible values.
  • 1 bit indicates the value is SET in a number
  • 0 bit indicates the value is UNSET in a number
For Bit Maps 
  •     OR (|)  is used to set the bit (e.g  n |= (1<<x) )
  •     AND (&) is used to clear the bit  (e.g   n &= ~(1<<x))
 How to Implement the Bit Maps?

Step 1:  Create a bit Map Array.
             unsigned char bit_map[2];

Step 2: Calculate the Bit Map array Index and shift index (How many bits needs to shift).
            < If the user gives  bit_position  input starts from 1>
            bit_map_array_index = (bit_position - 1) /8   
            shift_Index = (bit_position - 1)%8

           < If the user gives  bit_position  input starts from 0>
            bit_map_array_index = bit_position /8   
            shift_Index = bit_position %8

Step 3: Set the Bit in the Bit Map using
            bit_map[bit_map_array_index] |= (1<<shift_Index)

Step 4: Clear the Bit in the Bit Map using
            bit_map[bit_map_array_index] &=  ~(1<<shift_Index)

 Please find the below program for Better Understanding of Bit Maps in C.

#include<stdio.h>
#include<stdlib.h>

#define EXIT 100

#define BITMAP_LEN 2
#define BYTE_LEN   8

/* Debug OutPut */
void printTheDebugOutput(unsigned char *bit_array)
{
   int i, j;

   /* Array is 2 bit_array[0] and [1] */
   for (i=0 ; i<BITMAP_LEN; i++)
   {
     /* Bits 0..7 */
     for(j=1; j<=BYTE_LEN; j++)
     {
        if(bit_array[i] & (1 << (j-1)))
        {
           printf("In BIT_MAP[%d] the position of Bit SET : %d\n",
                                   i, j);
        }
     }
   }
}

/*
 *  Main() function
 */
int main()
{

  unsigned int bit_position, setOrUnsetBit, ch;

  unsigned char bit_Map_array_index, shift_index;

  /* Declare Bit Array and intialised to Zero
   * This BIT_MAP is generally assigned to one domain.
   * Here BIT MAP (Array of Bits) are used for Debugging Mechanism
   */
  unsigned char bit_map[BITMAP_LEN] = { 0 };
 
  /* In Bit- Maps , there are two options,
   * either  Set (OR |) or  Unset (AND &) bit.
   */
 do
 {
    /* Here the Max number of bits is 16 ranging from 1..16 */
    printf("Enter the Bit position (bit starts from 1 and Ends at 16) \n");
    scanf("%d", &bit_position); 

    /*
     * Set/Unset the Bit Map indicates which bits you want to enable 
     */
    printf(" Do you want to set/unset the Bit (1 or 0) \n");
    scanf("%d", &setOrUnsetBit);

    /* LOGIC as follows */
    /* Find Out the Index and and as well as Shift Index */

    /* It Give output as 0 or 1 ( for Bit Position 1..16) */
    bit_Map_array_index = (bit_position-1) / 8;

    /* Always give output as 0...7 ( for Bit Position 1..16)*/
    shift_index =  (bit_position-1) % 8;

    printf("The bit_position : %d shift Index : %d\n", bit_position, shift_index);

    /* If set is true */
    if( setOrUnsetBit)
     {        
       /* Set the Bit Array */
       bit_map[bit_Map_array_index] |= 1<<shift_index;
               
     }
    else
     { 
        /* Clear the Bit Array */ 
        bit_map[bit_Map_array_index] &= ~(1<<shift_index);
        
     }
    printf(" The Bit MAP Array : %d\n", bit_map[bit_Map_array_index]);
    printTheDebugOutput(bit_map);
   
    printf(" Do You want to Continue then Enter any Number"
           "and for Exit then enter 100\n");
    scanf("%d", &ch);

  }while(ch != 100);

 return 0;
}



Please refer in the blog for DEBUG LOG IMPLEMENTATION USING BIT MAP.



Friday, 5 July 2013

BIT WISE Operators -> C Interview Questions

Hi All,

  In this post, i would like to show frequently asked C-FAQs that are being encountered in interviews.

BIT-WISE Operators C-Faqs:

1. How to set particular bit in a number?
To set any bit in a number, Use (OR ) operator.

Number = Number | (1<<x)
'x' indicates the position of the bit
 

2. How to clear particular bit in a number?
To clear any bit in a number, Use (AND ) and (NEG (~)) operator.

Number = Number & ~(1<<x)
 
3. How to toggle or flip particular bit in a number?
 To toggle any bit in a number, Use (^ ) exclusive OR operator. 


Number = Number ^ (1<<x)

4.How to check particular bit is set or not in a number?
To check any bit in a number, Use (& ) And Operator . 

Number & (1<<x) 
                                                      'x' indicates the position of the bit  

5. How to represent the above in MACRO's for Real time code?

#define SET_BIT(Number, bit_position)    Number |= (1<< bit_position)

#define CLEAR_BIT(Number, bit_position)    Number &= ~(1<< bit_position)

#define TOGGLE_BIT(Number, bit_position)    Number ^= (1<< bit_position) 

#define CHECK_BIT_IS_SET_OR_NOT(Number, bit_position)    Number & (1<< bit_position)

6. How to check the number is Even or Odd?

#include<stdio.h>
int main()
{
  int number;
  printf("Enter the Number \n");
  scanf("%d", &number);

  if(number & 1)
    printf(" It is ODD number \n");
  else
    printf(" It is Even number \n");
}
 

6. How to count number of  1's or bits set in a number ?

#include<stdio.h>
int main()
{
  int n, count=0;
  printf(" Enter the Number :\n");
  scanf(" %d", &n);

  while(n)
  {
    n = n&(n-1);
    count ++;
  }
  printf(" No of Bits set count in the Number is %d\n", count);
  return 0;
}

 

7. How to count number of  0's or bits unset in a number ?
 
#include<stdio.h>
#define CHAR_BYTE 8
int main()
{
  unsigned int num, count =0, index;
  printf(" Enter the Integer \n");
  scanf("%d", &num);

  for(index = 0; index < (CHAR_BYTE * sizeof(int)); index++)
  {
     /* check the Bit is Set to Zero */
     if((num & (1 << index)) == 0)
     {
        count ++;
     }

  }
  printf(" The Number of Zero's present in Integer: %d\n", count);
  return 0;
}

 8. How to find out a number  is power of 2  or not? 

 #include<stdio.h>
int main()
{
  unsigned int n;
  printf("Enter the Number \n");
  scanf("%d", &n);

  if((n != 0) && (n & (n-1)) )
      printf(" It is Not power of 2\n");
  else
      printf(" It is power of 2\n");

 return 0;
}



 9. How to Swap two numbers using Bit Wise Operators?  ( Remember as -> (ab, ba, ab)

#include<stdio.h>
int main()
{
   int a, b;
   printf(" Enter the Value of a and b\n");
   scanf("%d %d", &a, &b);
   a = a ^ b;
   b = b ^ a;
   a = a ^ b;
   


/*
   or 
   a = a + b;
   b = a - b;
   a = a - b;
   */
 

   printf("Value of a : %d and b : %d\n", a, b);  
   return 0;
}

10. How to reverse a string with out using Temporary variable?

#include<stdio.h>
#include<string.h>

#define LEN 100 /* Can be changed */
int main()
{
   char str[LEN];   
   unsigned int end, start=0;

   printf(" Enter the String to be reversed  \n");
   scanf("%s", str);

   /* Find out the string Length */
   end = strlen(str)-1;
   /* Iterate through start less than end */
   while(start < end)  
   {
     str[start]   ^= str[end];
     str[end]     ^= str[start];
     str[start]   ^= str[end];
    
     start++;
     end --;
   }

   printf("The Reverse string is : %s\n", str);
   return 0;
}



10. How to reverse Bits of a Number?

#include<stdio.h>
#define SIZE_OF_CHAR 8
int main()
{

    unsigned int i, num, reverse_num= 0;
    unsigned int NO_OF_BITS;

    printf("Enter the number to be reversed \n");
    scanf("%d", &num);

    NO_OF_BITS = SIZE_OF_CHAR * (sizeof(num));

   for(i=0; i<NO_OF_BITS; i++)
   {
       if(num & (1<<i))          -> This similar Logic is used to count 1's & 0's in a number.
       {
           reverse_num = reverse_num | (1<< ((NO_OF_BITS -1)-i));
       }
   }

   printf(" The reverse Num is %d", reverse_num);

}

Please refer the BITMAP tutorial in the BLOG, It is really useful for real time applications.

Monday, 27 May 2013

What is EPOLL? Epoll vs Poll vs Select call ? And How to implement UDP server in Linux using EPOLL?



Today in internet world, as the number of users are increasing day to day and to support these users it needs more efficient HTTP servers.

A common problem in HTTP server scalability is how to ensure that the server handles a large number of connections simultaneously without degrading the performance.

An event-driven approach is often implemented in high-performance network servers to multiplex a large number of concurrent connections over a few server processes. 

In event-driven servers it is important that the server focuses on connections that can be serviced without blocking its main process.

What is EPOLL?
===========
epoll - I/O event notification facility

Select Vs poll Vs Epoll
==================
The Epoll event mechanism  is designed to scale to larger numbers of connections than select and poll.

One of the problems with select and poll is that in a single call they must both inform the kernel of all of the events of interest and obtain new events.
This can result in large overheads, particularly in environments with large numbers of connections and relatively few new events occurring.

However, if your server application is network-intensive (e.g., 1000s of concurrent connections and/or a high connection rate), you should get really serious about performance.
This situation is often called the c10k problem. With select() or poll(), your network server will hardly perform any useful things but wasting precious CPU cycles under such high load.

c10k Problem
===========
Suppose that there are 10,000 concurrent connections. Typically, only a small number of file descriptors among them, say 10, are ready to read.
The rest 9,990 file descriptors are copied and scanned for no reason, for every select()/poll() call.

Another Example as :

The cost of  Epoll is closer to the number of file descriptors that actually have events on them.
If you're monitoring 200 file descriptors, but only 100 of them have events on them, then you're (very roughly) only paying for those 100 active file descriptors.
This is where Epoll tends to offer one of its major advantages over select. If you have a thousand clients that are mostly idle,
then when you use select you're still paying for all one thousands of them. However, with Epoll, it's like you've only got a few - you're only paying for the ones that are active at any given time.

All this means that epoll will lead to less CPU usage for most workloads

Time Complexity
=============

Select  -> O(n)   Epoll -> O(1)

Select calls, which are O(n), epoll is an O(1) algorithm – this means that it scales well as the number of watched file descriptors increase.
select uses a linear search through the list of watched file descriptors, which causes its O(n) behaviour, whereas epoll uses callbacks in the kernel file structure.

Another fundamental difference of epoll is that it can be used in an edge-triggered, as opposed to level-triggered, fashion.
 This means that you receive “hints” when the kernel believes the file descriptor has become ready for I/O, as opposed to being told “I/O can be carried out on this file descriptor”.

No of clients support is a Limitation in Select Call
==============================================
Using Select() call, Max number of clients it handle is 1024 (1k).

In other words, server is able to handle only 1024 client after which connections are failing.
Increased per process max open files (1024) to 100000 and still the connections failed at 1024.

select limitation

select fails after 1024 fds as FD_SETSIZE max to 1024.
As a natural progression poll was tried next to overcome max open fd issue.

poll limitation
poll solves the max fd issue. But as the number of concurrent clients started increasing, performance dropped drastically.
Poll implementation does O(n) operations internally and performance drops as number of fds increases.

epoll
Epoll solved both problems and gave awesome performance.

Triggering modes
=============

  • Edge Triggered Mode
  •  Level Triggered Mode

Epoll provides both edge-triggered and level-triggered modes. 

In edge-triggered mode, a call to epoll_wait will return only when a new event is en queued with the epoll object, while in level-triggered mode, epoll_wait will return as long as the condition holds.

For instance, if a pipe, registered with epoll, has received data, a call to epoll_wait will return, signaling the presence of data to be read.
Suppose the reader only consumed part of data from the buffer. In level-triggered mode, further calls to epoll_wait will return immediately, as long as the pipe's buffer contains data to be read.
In edge-triggered mode, however, epoll_wait will return only once new data is written to the pipe

To Understand Better…..

When an FD becomes read or write ready, you might not want necessarily want to read (or write) all the data immediately.

Level-triggered epoll will keep nagging you as long as the FD remains ready, whereas edge-triggered won't bother you again until the next time you get an EAGAIN
(so it's more complicated to code around, but can be more efficient depending on what you need to do).

Say you're writing from a resource to an FD. If you register your interest for that FD becoming write ready as level-triggered, you'll get constant notification that the FD is still ready for writing.
If the resource isn't yet available, that's a waste of a wake-up, because you can't write any more anyway.

If you were to add it as edge-triggered instead, you'd get notification that the FD was write ready once, then when the other resource becomes ready you write as much as you can.
Then if write(2) returns EAGAIN, you stop writing and wait for the next notification.

The same applies for reading, because you might not want to pull all the data into user-space before you're ready to do whatever you want to do with it
 (thus having to buffer it, etc etc). With edge-triggered epoll you get told when it's ready to read, and then can remember that and do the actual reading "as and when".

EPOLL SYSTEM Calls
==================

The Epoll interface consists of three system calls:

int epoll_create(int size);

Creates an epoll object and returns its file descriptor. size is obsolete since kernel 2.6.8 but must be greater than zero for backwards compatibility.

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

Controls (configures) which file descriptors are watched by this object, and for which events. op can be ADD, MODIFY or DELETE.

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

Waits for any of the events registered for with epoll_ctl, until at least one occurs or the timeout elapses. Returns the occurred events in events, up to maxevents at once.


 UDP SERVER IMPLEMENTED USING EPOLL
==========================================


#include <stdio.h>          // for printf() and fprintf()
#include <sys/socket.h>     // for socket(), bind(), and connect()
#include <arpa/inet.h>      // for sockaddr_in and inet_ntoa()
#include <stdlib.h>         // for atoi() and exit()
#include <string.h>         // for memset()
#include <unistd.h>         // for close()
#include <fcntl.h>          // for fcntl()
#include <errno.h>
#include <sys/epoll.h>

#define MAX_EVENTS 100

#define BUFFSIZE 5096

unsigned char buf[BUFFSIZE];

/*
 * Dump Data
 */
void dumpData(unsigned char *data,  unsigned int len)
{
  unsigned int uIndx;

  if(data)
    {
      for(uIndx=0; uIndx<len; ++uIndx)
        {
          if(uIndx%32 == 0)
            {
              printf("\n%4d:", uIndx);
            }
          if(uIndx%4 == 0)
            {
              printf(" ");
            }
          printf("%02x", data[uIndx]);
        }
    }
  printf(" Length of Bytes: %d\n", len);
  printf("\n");
}


/*
 * make_socket_non_blocking :
 *   This Function makes socket as Non blocking
 */
static int make_socket_non_blocking(int sockFd)
{
  int getFlag, setFlag;
 
  getFlag = fcntl(sockFd, F_GETFL, 0);
 
  if(getFlag == -1)
  {
    perror("fnctl");
    return -1;
  }
 
  /* Set the Flag as Non Blocking Socket */
  getFlag |= O_NONBLOCK;
 
  setFlag = fcntl(sockFd, F_GETFL, getFlag);
 
  if(setFlag == -1)
  {
    perror("fnctl");
    return -1;
  }
 
  return 0;
}

/*
 *  Main Routine
 */
int main()
{
  int i, length, receivelen;

  /* Socket Parameters */
  int sockFd;
  int optval = 1;   // Socket Option Always = 1

  /* Server Address */
  struct sockaddr_in serverAddr, receivesocket;

  /* Epoll File Descriptor */
  int epollFd;      

  /* EPOLL Event structures */
  struct epoll_event  ev;                  
  struct epoll_event  events[MAX_EVENTS];               
  int numEvents;    
             
  int ctlFd; 
  // Step 1: First Create UDP Socket 
 
  /* Create UDP socket
   * socket(protocol_family, sock_type, IPPROTO_UDP);
   */
  sockFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

  /* Check socket is successful or not */
  if (sockFd == -1)
  {
    perror(" Create SockFd Fail \n");
    return -1;
  }

  // Step 2: Make Socket as Non Blocking Socket.
  //         To handle multiple clients Asychronously, required to
  //         configure socket as Non Blocking socket

  /* Make Socket as Non Blocking Socket */
  make_socket_non_blocking(sockFd);

  // Step 3: Set socket options
  //    One can set different sock Options as RE-USE ADDR, 

  //    BROADCAST etc.
 
  /*  In this Program, the socket is set to RE-USE ADDR
   *  So this gives flexibilty to other sockets to BIND to the 

      same port Num */

  if(setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))== -1)
  {
     perror("setsockopt Fail\n");
     return -1;
  }

  // Step 4: Bind to the Recieve socket
  /* Bind to its own port Num  ( Listen on Port Number) */
  
  /* Setup the addresses */
 
   /* my address or Parameters
     ( These are required for Binding the Port and IP Address )
      Bind to my own port and Address */
  memset(&receivesocket, 0, sizeof(receivesocket));
  receivesocket.sin_family = AF_INET;
  receivesocket.sin_addr.s_addr = htonl(INADDR_ANY);
  receivesocket.sin_port = htons(2905);

  receivelen = sizeof(receivesocket);

  /* Bind the my Socket */
  if (bind(sockFd, (struct sockaddr *) &receivesocket, receivelen) < 0)
  {
    perror("bind");
    return -1;
  }

  // EPOLL Implementation Starts
  // Step 5: Create Epoll Instance
             /* paramater is Optional */
 
  epollFd = epoll_create(6);

  if(epollFd == -1)
  {
     perror("epoll_create");
     return -1;
  }

  /* Add the udp Sock File Descriptor to Epoll Instance */
  ev.data.fd = sockFd;
 
  /* Events are Read Only and Edge-Triggered */
  ev.events = EPOLLIN | EPOLLET;

 
  // Step 6: control interface for an epoll descriptor
  /* EPOLL_CTL_ADD
      Register the target file descriptor fd on the epoll instance
      referred to by the file descriptor epfd and
      associate the event event with the internal file linked to fd.
  */


  /* Add the sock Fd to the EPOLL */
  ctlFd  = epoll_ctl (epollFd, EPOLL_CTL_ADD, sockFd, &ev);
 
  if (ctlFd == -1)
  {
    perror ("epoll_ctl");
    return -1;
  }

 // Step 7: Start the Event Loop using epoll_wait() in while Loop.

 /* Event Loop */
 while(1)
 {
     /*  Wait for events.
      *  int epoll_wait(int epfd, struct epoll_event *events, int
      *  maxevents, int timeout);
      *  Specifying a timeout of -1 makes epoll_wait() wait
      *  indefinitely.
      */
    
     /* Epoll Wait Indefently since Time Out is -1 */
     numEvents = epoll_wait(epollFd, events, MAX_EVENTS, -1);

     for (i = 0; i < numEvents; i++)
     {
       if ((events[i].events & EPOLLERR) ||
           (events[i].events & EPOLLHUP) ||
           (!(events[i].events & EPOLLIN)))
        {
           /* An error has occured on this fd, or  the socket is not
            * ready for reading (why were we notified then?)
            */
           fprintf (stderr, "epoll error\n");
           close (events[i].data.fd);
           continue;
        }
       /* We have data on the fd waiting to be read. Read and
        * display it. We must read whatever data is available
        * completely, as we are running in edge-triggered mode
        * and won't get a notification again for the same data.
        */
       else if ( (events[i].events & EPOLLIN) &&
           (sockFd == events[i].data.fd) )
       {
         while (1)
         {

           memset(buf, 0, BUFFSIZE);
           /* Recieve the Data from Other system */
           if ((length = recvfrom(sockFd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
            {
                perror("recvfrom");
                return -1;
            }

           else if(length == 0)
             {
               printf( " The Return Value is 0\n");
               break;
             }
           else
             {
               /* Print The data */
               printf("Recvd Byte length : %d",  length);
               dumpData(buf, length);
             }
          }
       }
     }
  }

close( sockFd );
close( epollFd );
return 0;
}



==============================================================================
UDP CLIENT -> udpclient.c
==============================================================================

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include<stdlib.h>
#include <sys/unistd.h>
#include <sys/fcntl.h>


#define BUFFSIZE 5096
#define MAX_LEN 100000

int sendlen, receivelen;
int received = 0, i,count, rcvCnt=0, sentCnt=0;
unsigned char buffer[BUFFSIZE];
struct sockaddr_in receivesocket;
struct sockaddr_in sendsocket;
int sock;
unsigned int ch;
unsigned int noOfTimes;
   
int sendUDPData();  
   
int main(int argc, char *argv[]) {
   
    int ret = 0;
  int optval = 1;

    /* Create the UDP socket */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        perror("socket");
        return -1;
    }

    /* my address */
    memset(&receivesocket, 0, sizeof(receivesocket));
    receivesocket.sin_family = AF_INET;
    receivesocket.sin_addr.s_addr = htonl(INADDR_ANY);
    receivesocket.sin_port = htons(2905);

    receivelen = sizeof(receivesocket);

 if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))== -1)
  {
     perror("setsockopt Fail\n");
     return -1;
  }
  if (bind(sock, (struct sockaddr *) &receivesocket, receivelen) < 0) 

    {
        perror("bind");
        return -1;      
    } 
    /* kernel address */
    memset(&sendsocket, 0, sizeof(sendsocket));
    sendsocket.sin_family = AF_INET;
    sendsocket.sin_addr.s_addr = inet_addr("10.12.7.95");
    sendsocket.sin_port = htons(2905);

   do
    {
       printf("\n");
       printf(" Enter your choice:\t");
       printf(" 1. Send UDP Data \n");
       printf(" 2. exit \n");
       scanf("%d", &ch);
       printf("\n");

       switch(ch)
       {

           case 1:
                   printf("Enter the Length of the Payload \n");
                   scanf("%d", &sendlen);
                   printf("Enter How many times you want to send data \n");
                   scanf("%d", &noOfTimes);
                   sendUDPData();
                   break;

           default:
                  printf("Invalid Choice\n");
                  break;
       }
    }while(ch!=2);
return 0;
}
int sendUDPData()
{
    int count=0;
        memset(buffer, 0x31, sendlen);
       
        for(count=0; count< noOfTimes;  count++)
        {
       if (sendto(sock, buffer, sendlen, 0, (struct sockaddr *) &sendsocket,
                        sizeof(sendsocket)) != sendlen)      
       {
        perror("sendto");
        return -1;
       }

    printf("\n");
    }
    return 0;
}