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
10 More Discussions You Might Find Interesting
1. UNIX for Dummies Questions & Answers
How do I use snoop command to capture multicast packets in the network? (1 Reply)
Discussion started by: caden312
1 Replies
2. Solaris
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
3. HP-UX
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
4. HP-UX
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
5. Linux
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
6. Solaris
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
7. UNIX for Advanced & Expert Users
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
8. Shell Programming and Scripting
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
9. Solaris
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
10. IP Networking
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