Ubuntu 10.04 + Multicast Receiver c++


 
Thread Tools Search this Thread
Top Forums Programming Ubuntu 10.04 + Multicast Receiver c++
# 1  
Old 07-13-2011
Ubuntu 10.04 + Multicast Receiver c++

Hello all,

I have created a UDP multicast transmitter and receiver, first using windows. But now I need the receiver to run on Ubuntu 10.04.

The code is the following:
Code:
/************************** Receiver *************************/
// Module Name: Receiver.c
//
// Description:
//    This sample receives UDP datagrams by binding to the specified
//    interface and port number and then blocking on a recvfrom()
//    call
/************************** Receiver *************************/

#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string.h>

#include <stdbool.h>

#include <sys/types.h> // data types
#include "sys/socket.h"
#include <netinet/in.h>    // internet address family
#include <arpa/inet.h>  // internet operations

typedef unsigned long DWORD;
using namespace std;

int    iPort = 1234; // Port to receive on
DWORD    dwCount, // Number of messages to read
    dwLength; // Length of receiving buffer
int    packet_length,
    remainder;
bool bInterface = true; // Use an interface other than default
char*    szInterface;  // Interface to read datagrams from
char*    multicast_grp_add;
char*    multicast_src_add;

char*    filename_video;
string    filename_video_seq;
char*    filename_file;
char*    filename_count;
int    max_burst_length        = 0;
int    current_burst_length            = 0;
int    prev_index            = 0;
int    current_index            = 0;

#define DWL 1316

//********************************************************************
// Function: SetArgs
// Description: Set Global Parameters
 //********************************************************************
void SetArgs()
{
    dwCount                = 1298;                //-c
    dwLength        = 1316;                //-l
    szInterface        =  "192.168.0.3";        //-i
    multicast_grp_add    = "236.0.0.5";            //-g
    multicast_src_add    = "192.168.2.2";        //-s
    filename_video        = "video_out.mp4";        //-v
    filename_video_seq    = "seq_video_out.mp4";
    filename_file        = "file_out.txt";        //-f
    filename_count        = "count_out.txt";        //-t
    packet_length        = dwLength - 6; 
    remainder        = 174;                //-r
}
//********************************************************************

//********************************************************************
// Function: ValidateArgs
//********************************************************************
// Description:
//    Parse the command line arguments, and set some global flags to
//    indicate what actions to perform
//********************************************************************
void ParseArgs(int argc, char* argv[])
{
    SetArgs();
    for (int i = 1; i < argc; i++)
    {
        if ((*(argv[i]+1) == 'c') || (*(argv[i]+1) == 'C'))
        {
            // the number of packets to receive
            cout << "the number of packets to receive" << endl;
            dwCount            = atol(argv[i+1]);
            cout << dwCount << endl;
        }
        else if ((*(argv[i]+1) == 'l') || (*(argv[i]+1) == 'L'))
        {
            // the number of characters to receive
            cout << "set dwLength" << endl;
            dwLength        = atol(argv[i+1]);
            cout << dwLength << endl;
            cout << "set packet_length" << endl;
            packet_length    = dwLength - 6;
            cout << packet_length << endl;
        }
        else if ((*(argv[i]+1) == 'r') || (*(argv[i]+1) == 'R'))
        {
            // Remainder
            cout << "Remainder" << endl;
            remainder        = atol(argv[i+1]);
            cout << remainder << endl;
        }
        else if ((*(argv[i]+1) == 'i') || (*(argv[i]+1) == 'I'))
        {
            // Interface of the current receiver
            cout << "set interface" << endl;
            szInterface        = argv[i+1];
            cout << szInterface << endl;
        }
        else if ((*(argv[i]+1) == 'g') || (*(argv[i]+1) == 'G'))
        {
            // multicast group address
            cout << "set multicast group address" << endl;
            multicast_grp_add = argv[i+1];
            cout << multicast_grp_add << endl;
        }
        else if ((*(argv[i]+1) == 's') || (*(argv[i]+1) == 'S'))
        {
            // multicast source address
            cout << "set multicast source address" << endl;
            multicast_src_add = argv[i+1];
            cout << multicast_src_add << endl;
        }
        else if ((*(argv[i]+1) == 'v') || (*(argv[i]+1) == 'V'))
        {
            // video file path
            cout << "set video" << endl;
            filename_video = argv[i+1];
            cout << filename_video << endl;
            filename_video_seq = filename_video;
            filename_video_seq.insert(0, "seq_");
            cout << filename_video_seq << endl;

        }
        else if ((*(argv[i]+1) == 'f') || (*(argv[i]+1) == 'F'))
        {
            // file path
            cout << "set file" << endl;
            filename_file = argv[i+1];
            cout << filename_file << endl;
        }
        else if ((*(argv[i]+1) == 't') || (*(argv[i]+1) == 'T'))
        {
            // count path
            cout << "set count" << endl;
            filename_count = argv[i+1];
            cout << filename_count << endl;
        }
        i++;
    }
}
//********************************************************************

//********************************************************************
//
// Function: main
//********************************************************************
// Description:
//    Main thread of execution. Initialize Winsock, parse the command
//    line arguments, create a socket, bind it to a local interface
//    and port, and then read datagrams.

int main(int argc, char* argv[])
{
  int s;
  int ret, i, n;
  int    count; // Keeps track of the number of packets received
  char count_s[50];
  DWORD index_dw;
  char index[7];
    
    struct sockaddr_in sender,local;
    socklen_t dwSenderSize;

    // Multicast
struct ip_mreq imr;

    char * str_rx_total;
   size_t total_b;
    //********************************************************************//
    // Parse arguments
    //********************************************************************//
      ParseArgs(argc, argv);    
    //********************************************************************//

ofstream out_video(filename_video, ios::out|ios::binary);
      // out_video will store packets exactly as received
      ofstream out_video_seq(filename_video_seq.c_str(), ios::out|ios::binary);
      // out_video_seq will store packets according to the index
      ofstream out_file(filename_file, ios::out);
      ofstream out_count(filename_count, ios::out);

    // total bytes to receive
    total_b          = packet_length*(dwCount-1)+ remainder;
    str_rx_total    = new (nothrow) char [total_b];
    if (!str_rx_total)
    {
        // error assigning memory to str_rx_total
    printf ("Error in creating str_rx_total\n");
    scanf("%*c");
    return 1;
    }

cout << total_b << endl;
    // set all values in str_rx_total to zero
    memset(str_rx_total, 0, total_b);
    
if (out_video && out_video_seq && out_file && out_count)
{
  //********************************************************************//
  // Create the socket
  //********************************************************************//
  s = socket(AF_INET, SOCK_DGRAM, 0);
  
  if (s<0)    
  {
    printf("socket() failed");
    scanf("%*c");
    out_video.close();
    out_video_seq.close();
    out_file.close();
    out_count.close();
    return 1;
  }
  cout << "socket success" << endl;
  //********************************************************************//

  int reuse = 1;
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof (reuse))<0)
    { 
      perror("Setting SO_REUSEADDR error");
      close(s);
      exit(1);
    }
  else 
    printf("Setting SO_REUSEADDR...OK.\n");
 

  //********************************************************************//
  // Bind the socket to an interface
  //********************************************************************//
  local.sin_family = AF_INET;
  local.sin_port   = htons((short)iPort);
  if (bInterface)
    {
        local.sin_addr.s_addr    = inet_addr(szInterface);
    }
  else
    {
      local.sin_addr.s_addr    = htonl(INADDR_ANY); 
    }
  if (bind(s, (struct sockaddr *)&local, sizeof(local)) < 0)
    {
      printf("bind() failed");
      scanf("%*c");
      out_video.close();
      out_video_seq.close();
      out_file.close();
      out_count.close();
      return 1;
    }

  cout << "bind success" << endl;
        
  imr.imr_interface.s_addr    = inet_addr(szInterface);
  // the interface of the receiver - ip address of the receiver
  imr.imr_multiaddr.s_addr    = inet_addr(multicast_grp_add);
  // ip address of the multicast group
  
  
if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, sizeof(imr)) < 0)
    {
      printf("Problem");
      scanf ("%*c");
      out_video.close();
      out_video_seq.close();
      out_file.close();
      out_count.close();
      return 1;
    }
  //********************************************************************//
 cout << "set socket ok" << endl;
        
//********************************************************************//
// Allocate the receive buffer
//********************************************************************//
        char recvbuf[DWL];
 //********************************************************************//

 //********************************************************************//
 // Read the datagrams
 //********************************************************************//
 count = 0;
 char * str_rx;
 str_rx = new (nothrow) char [packet_length];
 if (str_rx != 0)
   {
     for(i = 0; i < dwCount+3; i++)
       // +3 to include the quit signals
       {
     dwSenderSize = sizeof(sender);
     
     
     cout << "before read" << endl;
     int received = 0;
     if ((received =  recvfrom(s, &recvbuf, dwLength, 0, (struct sockaddr *)&sender, &dwSenderSize)) < 0)
       {
         printf("recvfrom() failed;\n");
         scanf("%*c");
         break;
       }
     else if (received == 0)
       break;
     else
       // received something
       // processing what was received
       {
           cout << "after read" << endl;
         recvbuf[received] = '\0';

         // output on screen
         printf("[%s] sent me:\n", inet_ntoa(sender.sin_addr));

         // append to out_file the index of the current packet
         for (int i = 0; i < 6; i++)
           {
         index[i] = *(recvbuf+i);
           }
         index[6] = '\n';
         out_file.write(index, 7);
         index_dw = atoi(index);
         //printf("index_dw = %d\n", index_dw);
printf("index_dw = %lu\n", index_dw);

         if (index_dw != 111111)
           {    // not quit signal

                        
         count++;
         printf("total packets received: %d\n", count);
         n = sprintf(count_s, "total received packets: %d\n", count);
         out_count.write(count_s, n);
                        
         current_index = index_dw;
         current_burst_length = current_index - prev_index;
         if (current_burst_length > max_burst_length)
           {
             // update variables
             max_burst_length = current_burst_length;
           }

         prev_index = current_index;


         // creating the video
         if (index_dw == dwCount-1)
           {
             // receive the last packet
             // therefore require only 'remainder' characters
             char * str_rx_remainder;
             str_rx_remainder = new (nothrow) char [remainder];
             if (str_rx_remainder != 0)
               {
             for (int index = 0; index < remainder; index++)
               {
                 *(str_rx_remainder+index) = *(recvbuf+6+index);
                 // 6 being the number of characters dedicated to the 
                 // sequence number of the packet

                 // update str_rx_total
                 *(str_rx_total+(index_dw*packet_length)+index) = *(recvbuf+6+index);
               }
                                
             printf("Extract %d\n", remainder);
             out_video.write(str_rx_remainder, remainder);
                                
               }
             else
               {
             // memory was not assigned correctly
             cout << "Error in assigning str_rx_remainder" << endl;
             scanf("%*c");
             out_file.close();
             out_video.close();
             out_count.close();
             exit(1);  
               }
           }
         else
           {
             // use all characters except the first 6 characters
             for (int index = 0; index < packet_length; index++)
               {
             *(str_rx+index) = *(recvbuf+6+index);
             // 6 being the number of characters dedicated to the 
             // sequence number of the packet

             //update str_rx_total
             *(str_rx_total+(index_dw*packet_length)+index) = *(recvbuf+6+index);
               }
             out_video.write(str_rx, packet_length);
           }
           }
         else
           {
         // quit signal
         // must exit
         //closesocket(s);
         close(s);
         out_video_seq.write(str_rx_total, total_b);

         out_video.close();
         out_video_seq.close();
         out_file.close();
         out_count.close();
         printf("max burst length: %d\n", max_burst_length);
         printf("exiting: please press any key");
         scanf("%*c");
         // WSACleanup();
         return 0;
           }
       }
       }
   }
 else
   {
     // memory was not assigned correctly
     cout << "Error in assigning str_rx" << endl;
     scanf("%*c");
     out_video.close();
     out_video_seq.close();
     out_file.close();            
     out_count.close();
     return 1;
   }

 
 close(s);
 out_file.close();
 out_count.close();
 out_video.close();

 out_video_seq.write(str_rx_total, total_b);
 out_video_seq.close();

 scanf("%*c");

 return 0;
 }
 else
   {
     // did not open the files correctly
     printf ("Problem opening files");
     scanf ("%*c");
     exit (1);
   }
}
/************************* End of Receiver **********************/

The problem is: the code just stops at recvfrom .. It does not work. It stops over there and returns nothing.
Can anyone please help me?

I can see the packets using tcpdump

Thanks a lot

Last edited by Franklin52; 07-13-2011 at 08:11 AM.. Reason: Please use code tags for code and data samples, thank you
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. IP Networking

Multicast IP address

Hi please help, theoretically I',m interested in starting a streaming service using multicast IP service. I'd like to know how do I get an IP address that I can send my data too? (please don't just point me too Internet Assigned Numbers Authority as ive been there and it just seem to state... (1 Reply)
Discussion started by: fishman2001
1 Replies

2. Solaris

Multicast address config lost

On Solaris OS, We use the following command to config the multicast address for NIC in order to process the multicast packets: # route add 228.228.228.228 10.101.10.2 Where " 228.228.228.228 " is the multicast for specified NIC ip 10.101.10.2 . Also use the netstat -nr, the above set could... (0 Replies)
Discussion started by: Frank2004
0 Replies

3. Shell Programming and Scripting

shell script to read a line in gps receiver log file and append that line to new file

Hi, I have gps receiver log..its giving readings .like below Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GPSD,R=1 $GPGSV,3,1,11,08,16,328,40,11,36,127,00,28,33,283,39,20,11,165,00*71... (3 Replies)
Discussion started by: gudivada213
3 Replies

4. UNIX for Advanced & Expert Users

multicast protocole in unix

hi, i'm using fedora. and i want to install mospf and pim sm services. i read that there is mgated daemon for mospf but i cant find it. can u tell me where to find it? and how to install it? (0 Replies)
Discussion started by: jalil smail
0 Replies

5. Solaris

multicast config

On SUN Solaris 10, if I want to multicast packets between nodes, whether it must config the multicast IP from OS, if yes, how to do it? (0 Replies)
Discussion started by: Frank2004
0 Replies

6. Linux

How to multicast on different IP network

On Linux, I have configured two different IP address for two network device eth0 ,eth1 , in my program, I want to multicast differently on these two network, I know it must add route for single network and I try to config another route for second network,but it can not work correctly, how to config... (0 Replies)
Discussion started by: Frank2004
0 Replies

7. HP-UX

How to multicast on different IP network

Hi, there On HP-UX, I want to multicast packets on two different IP network repectively. The two NIC are configured with two different IP. The routes are added with one default and one net for each IP . The multisender programs bind their own local IP, multireceiver programs add the... (0 Replies)
Discussion started by: Frank2004
0 Replies

8. HP-UX

multicast data can not receive

On HP-UX, we want to exchange data via multicast, there happen to meet a problem: sometimes the receiver that has joined the group can not receive the multicast data, but the recvfrom call returned no error. We have reconfig the network and added the default the route, but still can not fixed it,... (0 Replies)
Discussion started by: Frank2004
0 Replies

9. Solaris

How to assign multicast IP address

How can I assign multicast ip address to my Sun server. I need this configuration to set up weblogic in cluster mode. This setup needs a multicast IP address where the managed servers can broadcast their heartbeats. Thanks (0 Replies)
Discussion started by: krishan
0 Replies

10. UNIX for Dummies Questions & Answers

how to capture multicast packets using snoop

How do I use snoop command to capture multicast packets in the network? (1 Reply)
Discussion started by: caden312
1 Replies
Login or Register to Ask a Question