Thursday 21 March 2013

muti threaded broadcast


#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#define kPortNumber 1234
#define kBufferSize 1024
#define kMaxSockets 16



int transmit(char * data, int length) {

  int sock_fds[kMaxSockets];
 
  struct ifaddrs *addrs;
  if ( getifaddrs(&addrs) < 0 ) {
    // Error occurred
    return 0;
  }
 
  // Loop through interfaces, selecting those AF_INET devices that support broadcast, but aren't loopback or point-to-point
  const struct ifaddrs *cursor = addrs;
  struct sockaddr_in addr;
  int number_sockets = 0;
 
  while ( cursor != NULL && number_sockets < kMaxSockets ) {
    if ( cursor->ifa_addr->sa_family == AF_INET
            && !(cursor->ifa_flags & IFF_LOOPBACK)
            && !(cursor->ifa_flags & IFF_POINTOPOINT)
            &&  (cursor->ifa_flags & IFF_BROADCAST) ) {

      // Create socket
      sock_fds[number_sockets] = socket(AF_INET, SOCK_DGRAM, 0);
      if ( sock_fds[number_sockets] == -1 ) {
        // Error occurred
        return 0;
      }
     
      // Create address from which we want to send, and bind it
      memset(&addr, 0, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_addr = ((struct sockaddr_in *)cursor->ifa_addr)->sin_addr;
      addr.sin_port = 0;
     
      if ( bind(sock_fds[number_sockets], (struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
        // Error occurred
        return 0;
      }
     
      // Enable broadcast
      int flag = 1;
      if ( setsockopt(sock_fds[number_sockets], SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag)) != 0 ) {
        // Error occurred
        return 0;
      }
     
      number_sockets++;
    }
    cursor = cursor->ifa_next;
  }
 
  // Initialise broadcast address
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_BROADCAST;
  addr.sin_port = htons(kPortNumber);
 
  // Send through each interface
  int i;
  for ( i=0; i<number_sockets; i++ ) {
    if ( sendto(sock_fds[i], data, length, 0, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
      // Error occurred
      return 0;
    }
  }
 
  return 1;
}

int receive() {
 
  // Create socket
  int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
  if ( sock_fd == -1 ) {
    // Error occurred
    return 0;
  }
 
  // Create address from which we want to receive, and bind it
  struct sockaddr_in addr;
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(kPortNumber);
  if ( bind(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) {
    // Error occurred
    return 0;
  }
 
  char buffer[kBufferSize];
  int addr_len = sizeof(addr);
 
  while ( 1 ) {
   
    // Receive a message, waiting if there's nothing there yet
    int bytes_received = recvfrom(sock_fd, buffer, kBufferSize, 0, (struct sockaddr*)&addr, &addr_len);
    if ( bytes_received < 0 ) {
       // Error occurred
       return 0;
    }
   
    // Now we have bytes_received bytes of data in buffer. Print it!
    fwrite(buffer, sizeof(char), bytes_received, stdout);
    printf("\n");
  } 
}


int main(int argc, char** argv) {
  if ( argc < 2 ) {
    // No argument: Just listen
    printf("Listening...\n");
    if ( !receive() ) {
      printf("Error occurred: %s\n", strerror(errno));
      return 1;
    }
    return 0;
  }

  // Argument provided: Transmit this
  if ( transmit(argv[1], strlen(argv[1])) ) {
    printf("\"%s\" transmitted.\n", argv[1]);
  } else {
    printf("Error occurred: %s\n", strerror(errno));
    return 1;
  }
 
  return 0;
}

No comments:

Post a Comment

Have some problem with this code? or Request the code you want if you cant find it in Blog Archive.