views:

641

answers:

2

Ok, I'm still new to using C sockets, but I was wondering if there is a way to extract the IP address adding running setsockopt? If you'll look at my code below, I have everything in my multicast sockets ready to send except for defining the variable mc_addr which is my IP address. Am I doing anything wrong that's real noticeable? If so, feel free to let me know or offer your suggestions. Right now though, I'm mainly concerned about getting the variable mc_addr filled out. I've never programmed in C before (just python, C++, and since the beginning of this summer, objectove-C) , so this is why I don't know EVERYTHING there is to know about the C language and am seeking help.

File.h

#define MYPORT 5673         /* port for our multicast socket */

int sock;                   /* socket descriptor */
char send_str[MAX_LEN];     /* string to send */
struct sockaddr_in mc_addr; /* socket address structure */
unsigned int send_len;      /* length of string to send */
char* mc_addr_str;          /* multicast IP address */
unsigned short mc_port;     /* multicast port */
unsigned char mc_ttl;       /* time to live (hop count) */

File.c

mc_port = MYPORT;
/* create a socket for sending to the multicast address  */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    NSLog(@"ERROR: broadcastMessage - socket() failed");
    return 1;
}

/* set the TTL (time to live/hop count) for the send */
if ((setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, 
        (void*) &mc_ttl, sizeof(mc_ttl))) < 0) {
    NSLog(@"ERROR: broadcastMessage - setsockopt() failed");
    return 1;
}

// define the IP address we will be using
mc_addr = // ???

/* construct a multicast address structure */
memset(&mc_addr, 0, sizeof(mc_addr));
mc_addr.sin_family      = AF_INET;
mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
mc_addr.sin_port        = htons(mc_port);

/* clear send buffer */
memset(send_str, 0, sizeof(send_str));

while (fgets(send_str, MAX_LEN, stdin)) {
    send_len = strlen(send_str);

    /* send string to multicast address */
    if ((sendto(sock, send_str, send_len, 0, 
            (struct sockaddr *) &mc_addr, sizeof(mc_addr))) != send_len) {
        NSLog(@"ERROR: broadcastMessage - sendto() sent incorrect number of bytes");
        return 1;
    }

    /* clear send buffer */
    memset(send_str, 0, sizeof(send_str));
}

close(sock);
return 0;
+1  A: 

Here is a Multicast client example in C and, another here.
The relevant line from the first example is

saddr.sin_addr.s_addr = inet_addr("226.0.0.1"); //your mcast IP address

I am not sure how you could have been programming in C++ without understanding C.

nik
Back in the day, I programmed both C++ and C without understanding C. Obviously my code got a lot better once I did start to understand ;-)
Steve Jessop
+2  A: 

Looks correct to me - where you have the "define the IP address we will be using" you should just set mc_addr_str (mc_addr itself is filled out with the code you already have there, based on mc_addr_str). Something like:

mc_addr_str = "239.20.30.40";

It's really up to you what multicast address you choose - the one I've put there I just picked out of the "Administratively scoped" range. Your clients and server just have to agree on it beforehand (or negotiate it some other way, like the clients contact the server unicast to ask what the multicast address they should subscribe to is).

This site may help.

caf
What if I just did this? I'm pretty sure it would work, but I just want to confirm.mc_addr = IN_ADDR_ANY;
Josh Bradley
Nope, you need to set it to a multicast destination address, and IN_ADDR_ANY isn't a multicast destination.(mc_addr is the destination address - the source address would be set by bind(), but you're not calling bind() so it will just use the most appropriate local address, which is fine).
caf