Wednesday 1 February 2012

How to send and recieve data via UDP sockets?

What is UDP?
UDP is Layer 4 (Transport Layer ) protocol which is used for carrying the data from one peer to another peer.

UDP is Connection Oriented or Connection less Protocol?
UDP is connection less protocol, means there is no guarantee that packet is delivered or not.
This UDP sockets also called as Datagram sockets.

Connection Oriented Vs Connection Less

A packet transmitted in a connectionless mode is frequently called a datagram.

In connection-oriented communication the communicating peers must first establish a logical or physical data channel or connection in a dialog preceding the exchange of user data.

The connectionless communication mode has the advantage over a connection-oriented mode in that it has low overhead. It also allows for multicast and broadcast operations, which may save even more network resources when the same data needs to be transmitted to several recipients. In contrast, a connection is always unicast (point-to-point).


Unfortunately, in connectionless mode transmission of a packet, the service provider usually cannot guarantee that there will be no loss, error insertion, misdelivery, duplication, or out-of-sequence delivery of the packet. (However, the risk of these hazards may be reduced by providing a reliable transmission service at a higher protocol layer of the OSI Reference Model.)
Another drawback of the connectionless mode is that no optimizations are possible when sending several frames between the same two peers.

What is socket:
Socket is an endpoint of an inter process communication flow across a computer network.
Socket is useful to communicate between two different process.(e.g  client.exe  <-> server.exe ).

Types of Sockets:
  • Datagram Sockets
  • Stream Sockets
  • Raw Sockets

What is Socket Address:
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.


UDP Client and Server Communication:  

When UDP client wants to send any data to server, then UDP client should fill the server socket address parameters appropriately and call send function.  
Server socket address means server IP address and server Port number.

At server side, server socket should bind to a specific port number. The server just waits, listening on the specific port in which client is sending data.


Note:  client side server port and server side listening port should be same, Then only packets will reach.

How to create socket?

#include <sys/socket.h>

int socket(int domain, int type, int protocol);


e.g: sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
Returns sock file descriptor (sockfd) which can be used for sending and recieving data  

domain
Specifies the communications domain in which a socket is to be created.
type
Specifies the type of socket to be created.
protocol
Specifies a particular protocol to be used with the socket. Specifying a protocol of 0 causes socket() to use an unspecified default protocol appropriate for the requested socket type.
How to send Message on socket?

#include <sys/socket.h>

ssize_t sendto(int
socket, const void *message, size_t length,
       int
flags, const struct sockaddr *dest_addr,
       socklen_t
dest_len);


e.g:  
   /* Server Socket */
   struct sockaddr_in sendsocket;



  /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;
   sendsocket.sin_addr.s_addr = inet_addr("10.0.0.1");
   sendsocket.sin_port = htons(2905);//same port Num should mention at server side

if (sendto(sockfd, buffer, sendlen, 0,
           (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)

{
      perror("sendto");
      return -1;
}

socket
Specifies the socket file descriptor.
message
Points to a buffer containing the message to be sent.
length
Specifies the size of the message in bytes.
flags
It can be Zero
dest_addr
Points to a sockaddr structure containing the destination address. The length and format of the address depend on the address family of the socket.
dest_len
Specifies the length of the sockaddr structure pointed to by the dest_addr argument.

How to bind  to the socket?
Generally in UDP sockets binding should be done on the server sockets.
If there is a requirement  to send and receive the data in both client and server side , then binding is required in client side as well as server side.

In other words, where ever you have recvfrom() function, then should bind to that socket()

#include <sys/socket.h>


int bind(int
socket, const struct sockaddr *address,
       socklen_t
address_len);


e.g: bind to local address of the system, IP address and Port Num.


/* client Socket */
struct sockaddr_in receivesocket;

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(sock, (struct sockaddr *) &receivesocket, receivelen) < 0) 

{
     perror("bind");
     return -1;
}
 

 How to receive Message from socket?

#include <sys/socket.h>

ssize_t recvfrom(int
socket, void *restrict buffer, size_t length,
       int
flags, struct sockaddr *restrict address,
       socklen_t *restrict
address_len);



e.g:

unsigned char buf[5096];
    while(true)
    {
        memset(buf, 0, BUFFSIZE);


        /* Recieve the Data from Other system */
        if ((receivedLen = recvfrom(sockfd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
        {
                perror("recvfrom");
                return 0;
        }

        else
        {
            printf("Data");
        }
}



How to check in Linux machine on which port Server is listening?

> netstat -nlp | grep -i <PortNum>

UDP Client Code:


#include <stdio.h>
#include <iostream.h>
#include <string.h>
#include <arpa/inet.h>
#include<sys/socket.h>

#define BUFFSIZE 5096

int sendlen, sentCnt;

unsigned char buffer[BUFFSIZE];

/* Server Socket */
struct sockaddr_in sendsocket;

/* Sock FD */
int sockFd;

/* Number of Times you need */
unsigned int ch;
unsigned int noOfTimes;

/* Send UDP Data */
int sendUDPData();

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

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

   /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;


   /* server Machine IP address as 10.1.1.1 and Having Port Num 2905 */
   sendsocket.sin_addr.s_addr = inet_addr("135.254.253.241");
   sendsocket.sin_port = htons(2905);

   /* Do Loop -> Send UDP Data */
   do
    {
       cout<<endl;
       cout<<" Enter your choice:\t"<<endl;
       cout<<" 1. Send UDP Data" <<endl;
       cout<<" 2. exit" <<endl;
       cin>>ch;
       cout<<endl;

       switch(ch)
       {
           case 1:
                   cout<<"Enter the Length of the Payload "<<endl;
                   cin>>sendlen;
                   cout<<"Enter How many times you want to send data "<<endl;
                   cin>>noOfTimes;
                   /* Send UDP Data */
                   sendUDPData();
                   break;

           default:
                  cout<<"Invalid Choice\n";
                  break;
       }
   }while(ch!=2);
   return 0;

}

int sendUDPData()
{
    int count=0;

    /* Memset the Buffer */
    memset(buffer, 0x2, sendlen);

    /* Number of Times we need to send the packet */
    for(count=0; count< noOfTimes;  count++)
    {
         /* Send the UDP Data */
         if (sendto(sockFd, buffer, sendlen, 0,
            (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)    

         {
                perror("sendto");
                return -1;
         }
         else
         {
                sentCnt++;
         }
   }
   return 0;
}

Server Code.

#include <stdio.h>
#include <iostream.h>
#include <arpa/inet.h>
#include <string.h>

#define BUFFSIZE 5096

unsigned char buf[BUFFSIZE];

/* client Socket */
struct sockaddr_in receivesocket;

/* Sock FD */
int sockFd;

void dumpData(unsigned char *data,  unsigned int len);

int main(int argc, char *argv[])
{
   int receivelen= 0, length;

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

   /* 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;
   }
   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 0;
        }
        else if(length == 0)
        {
             cout<< " The Return Value is 0";
        }
        else
        {
              /* Print The data */
             cout<< " Recvd Byte length" << length <<endl;
             dumpData(buf, length);
        }
   }
}
/*
 * 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");
}

Both send and Receive in one File:

#include <stdio.h>
#include <iostream.h>
#include <arpa/inet.h>
#include <string.h>

#define BUFFSIZE 5096

int sendlen, receivelen;
int i,count, sentCnt=0;
unsigned char buffer[BUFFSIZE];
/* client Socket */
struct sockaddr_in receivesocket;
/* Server Socket */
struct sockaddr_in sendsocket;

/* Sock FD */
int sockFd;

/* Number of Times you need */
unsigned int ch;
unsigned int noOfTimes;

/* Send UDP Data */
int sendUDPData();

/* Receive Call Back Function */
void *recvNetfilterData(void *);


int main(int argc, char *argv[]) {
int ret = 0;

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

   /* 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;
   }

   /* Server address or Parameters , Sending System Address and Port Num */
   memset(&sendsocket, 0, sizeof(sendsocket));
   sendsocket.sin_family = AF_INET;
   /* give Proper IP address */
   sendsocket.sin_addr.s_addr = inet_addr("10.1.1.1");
   sendsocket.sin_port = htons(2905);

   /* Create Seperate Thread */
   /* Start the Receiving Thread */

   pthread_t threadId;
   if(pthread_create(&threadId, NULL, recvNetfilterData, NULL))
   {
       cout<<"Error in creating receiver thread";
       return 0;
   }


   /* Do Loop -> Send UDP Data */
   do
    {
       cout<<endl;
       cout<<" Enter your choice:\t"<<endl;
       cout<<" 1. Send UDP Data" <<endl;
       cout<<" 2. exit" <<endl;
       cin>>ch;
       cout<<endl;

       switch(ch)
       {

           case 1:
                   cout<<"Enter the Length of the Payload "<<endl;
                   cin>>sendlen;
                   cout<<"Enter How many times you want to send data "<<endl;
                   cin>>noOfTimes;
                   /* Send UDP Data */
                   sendUDPData();
                   break;

           default:
                  cout<<"Invalid Choice\n";
                  break;
       }
 }while(ch!=2);
return 0;
}
/*
 *  sendUDPData
 */
int sendUDPData()
{
        int count=0;
        memset(buffer, 31, sendlen);

        for(count=0; count< noOfTimes;  count++)
        {
           /* Send the UDP Data */
           if (sendto(sockFd, buffer, sendlen, 0,
                (struct sockaddr *) &sendsocket, sizeof(sendsocket)) != sendlen)                   {
                perror("sendto");
                return -1;
           }
           else
           {
                sentCnt++;
           }
         }
    return 0;
}
/*
 * 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");
}

/*
 * recvNetfilterData()
 */
void *recvNetfilterData(void *args)
{
    unsigned char buf[5096];
    int receivedLen = 0;

    while(true)
    {
        memset(buf, 0, BUFFSIZE);
        /* Recieve the Data from Other system */
        if ((receivedLen = recvfrom(sockFd, buf, BUFFSIZE, 0, NULL, NULL)) < 0)
        {
  perror("recvfrom");
                return 0;
        }
        else if(receivedLen == 0)
        {
             cout<< " The Return Value is 0";
        }
        else
        {
              /* Print The data */
             cout<< " Recvd Byte length" << receivedLen <<endl;
             dumpData(buf, receivedLen);
        }
    }
}


       Note: Change IP address and Port Number appropriately while sending /Recieving data. 
                 Sending Port Number and Listening port Number should be same.                                  

1 comment:

  1. It is amazing that you have finally reached this point. i think that you had to overcome many obstacles that require the good physical availability.

    ReplyDelete