[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [linux_var] Messaggi in broadcast lan



:)
ci sono riuscito, se qualcuno vuole provare allego i sorgenti
attualmente un server invia e 8 clients ricevono in contemporanea la stessa notifica, in multicast.
Il server esegue il programma ad ogni invio
Il client invece rimane in ascolto. L'ho piazzato in .config/autostart di ogni utente cosi quando fanno login eseguono il programma in background. (Mi sovviene un dubbio sul fatto del logout login.... mi sa che devo rivedere il client se no ad ogni login mi rilancia il programma...:D)

per compilare:
gcc -o nomesender sender.c
gcc -o nomereceiver receiver.c

esempio per lanciare il client receiver
./nomereceiver 239.0.0.1 3000 192.168.1.100
(L'ip finale deve essere quello del server. E' una mezza sicurezza che ho messo)
esempio per lanciare il sender
./nomesender 239.0.0.1 3000 4000 face-cool Test "Nuovo messaggio"

se i 2 comandi vengono dati senza parametri esce una sorta di help:

sender
Usage: ./sen <Multicast IP> <Multicast Port> <millisec> <icon> <object> <message>
 Example: ./sender 239.0.0.1 3000 2000 face-cool Subject: "Hello world"

i parametri da dare a sender sono gli stessi di notify-send (quelli usabili) e tutti obbligatori

receiver
Usage: ./rec <Multicast IP> <Multicast Port> <IP to listen for>
(Note that notify-send must be installed)

Prendetelo cosi com'e'... un esperimento. 
Fa quello che mi serviva, ovvero quando la stampante riceve un fax e me lo salva in pdf sul server, questo se ne accorge tramite inotify e poi manda la notifica a tutti tramite il sender.
^^  :P



/* 23/03/2012 Filippi Christian  root2fox@gmail.com*/

/* Original source: http://www.nmsl.cs.ucsb.edu/MulticastSocketsBook/#cexamples

  The original example was intended to demostrate the simple trasmission 
  of strings in multicast, and was composed by sender and receive parts.

  I edited the code to use it like a multicast notifier using notify-send.

  Sender
  Events on server call the sender with parameters composing the message with 
  notify-send structure; the sender send the message in multicast and exit.

  Receiver
  All the receivers must be up and running and listening for all the incoming 
  messages from the multicast address & port but they are able to compute only 
  messages from one specified ip address (it's the only security control that 
  i've implemented... i know it's not so strong, but it's better than a punch 
  on the face and also i'm not so skilled to do better, sorry :-P )

  I don't know C language so maybe there is a better way... However it works :D 
*/
	
#include <sys/types.h>   /* for type definitions */
#include <sys/socket.h>  /* for socket API function calls */
#include <netinet/in.h>  /* for address structs */
#include <arpa/inet.h>   /* for sockaddr_in */
#include <stdio.h>       /* for printf() */
#include <stdlib.h>      /* for atoi() */
#include <string.h>      /* for strlen() */
#include <unistd.h>      /* for close() */

#define MAX_LEN  1024    /* maximum string size to send */
#define MIN_PORT 1024    /* minimum port allowed */
#define MAX_PORT 65535   /* maximum port allowed */

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

  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=1;     /* time to live (hop count) */
  char* time;		      /* specifies the timeout in milliseconds at which to expire the notification */
  char* icon;		      /* specifies an icon filename or stock icon to display */
  char* obj;		      /* message subject */
  char* message;	      /* message text */
  
  /* validate number of arguments */
  if (argc != 7) {
    fprintf(stderr, 
            "Usage: %s <Multicast IP> <Multicast Port> <millisec> <icon> <object> <message>\n Example: ./sender 239.0.0.1 3000 2000 face-cool Subject: \"Hello world\"\n", 
            argv[0]);
    exit(1);
  }

  mc_addr_str = argv[1];        /* arg 1: multicast IP address */
  mc_port     = atoi(argv[2]);  /* arg 2: multicast port number */
  time = argv[3];		/* arg 3: timeout in milliseconds */
  icon = argv[4];		/* arg 4: complete path for icon - or use stock name */
  obj = argv[5];		/* arg 5: message subject */
  message = argv[6];		/* arg 6: message text */

  /* validate the port range */
  if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT)) {
    fprintf(stderr, "Invalid port number argument %d.\n",
            mc_port);
    fprintf(stderr, "Valid range is between %d and %d.\n",
            MIN_PORT, MAX_PORT);
    exit(1);
  }

  /* create a socket for sending to the multicast address */
  if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    perror("socket() failed");
    exit(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) {
    perror("setsockopt() failed");
    exit(1);
  } 
  
  /* 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);

  /* Composing the command-message (the command stay in the receiver, we send only parameters across network. */
  sprintf(send_str,"%s%s%s%s%s%s%s%s%s", "-t ", time, " -i ", icon, " ", obj, " \"", message, "\"\n");
  send_len = strlen(send_str);
  
  /* Enable for debug */
  //printf("%s%s%s", "The message is: ", send_str, "\n");

  /* send string to multicast address */
  if ((sendto(sock, send_str, send_len, 0, (struct sockaddr *) &mc_addr, sizeof(mc_addr))) != send_len) {
    perror("sendto() sent incorrect number of bytes");
    exit(1);
  }

  close(sock);  

  exit(0);
}

/* 21/03/2012 Filippi Christian  root2fox@gmail.com*/

/* Original source: http://www.nmsl.cs.ucsb.edu/MulticastSocketsBook/#cexamples

  The original example was intended to demostrate the simple trasmission 
  of strings in multicast, and was composed by sender and receive parts.

  I edited the code to use it like a multicast notifier using notify-send.

  Sender
  Events on server call the sender with parameters composing the message with 
  notify-send structure; the sender send the message in multicast and exit.

  Receiver
  All the receivers must be up and running and listening for all the incoming 
  messages from the multicast address & port but they are able to compute only 
  messages from one specified ip address (it's the only security control that 
  i've implemented... i know it's not so strong, but it's better than a punch 
  on the face and also i'm not so skilled to do better, sorry :-P )

  I don't know C language so maybe there is a better way... However it works :D 
*/

#include <sys/types.h>  /* for type definitions */
#include <sys/socket.h> /* for socket API calls */
#include <netinet/in.h> /* for address structs */
#include <arpa/inet.h>  /* for sockaddr_in */
#include <stdio.h>      /* for printf() and fprintf() */
#include <stdlib.h>     /* for atoi() */
#include <string.h>     /* for strlen() */
#include <unistd.h>     /* for close() */

#define MAX_LEN  1024   /* maximum receive string size */
#define MIN_PORT 1024   /* minimum port allowed */
#define MAX_PORT 65535  /* maximum port allowed */

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

  int sock;                     /* socket descriptor */
  int flag_on = 1;              /* socket option flag */
  struct sockaddr_in mc_addr;   /* socket address structure */
  char recv_str[MAX_LEN+1];     /* buffer to receive string */
  int recv_len;                 /* length of string received */
  struct ip_mreq mc_req;        /* multicast request structure */
  char* mc_addr_str;            /* multicast IP address */
  unsigned short mc_port;       /* multicast port */
  struct sockaddr_in from_addr; /* packet source */
  unsigned int from_len;        /* source addr length */
  char buf[MAX_LEN+1];	
  char* str1 = "notify-send ";
  char* str2 = "\n";
  char* str3 = "\"";
  char* sender;			/*IP address to listen for */
  int i = 0;

  /* validate number of arguments */
  if (argc != 4) {
    fprintf(stderr, 
            "Usage: %s <Multicast IP> <Multicast Port> <IP to listen for>\n(Note that notify-send must be installed)\n", 
            argv[0]);
    exit(1);
  }

  mc_addr_str = argv[1];      /* arg 1: multicast ip address */
  mc_port = atoi(argv[2]);    /* arg 2: multicast port number */
  sender = argv[3];	      /* arg 3: ip address to listen for */

  /* validate the port range */
  if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT)) {
    fprintf(stderr, "Invalid port number argument %d.\n",
            mc_port);
    fprintf(stderr, "Valid range is between %d and %d.\n",
            MIN_PORT, MAX_PORT);
    exit(1);
  }

  /* create socket to join multicast group on */
  if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    perror("socket() failed");
    exit(1);
  }
  
  /* set reuse port to on to allow multiple binds per host */
  if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag_on,
       sizeof(flag_on))) < 0) {
    perror("setsockopt() failed");
    exit(1);
  }

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

  /* bind to multicast address to socket */
  if ((bind(sock, (struct sockaddr *) &mc_addr, 
       sizeof(mc_addr))) < 0) {
    perror("bind() failed");
    exit(1);
  }

  /* construct an IGMP join request structure */
  mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
  mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

  /* send an ADD MEMBERSHIP message via setsockopt */
  if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
       (void*) &mc_req, sizeof(mc_req))) < 0) {
    perror("setsockopt() failed");
    exit(1);
  }

  for (;;) {          /* loop forever */

    /* clear the receive buffers & structs */
    memset(recv_str, 0, sizeof(recv_str));
    from_len = sizeof(from_addr);
    memset(&from_addr, 0, from_len);
    memset(buf, 0, sizeof(buf));

    /* block waiting to receive a packet */
    if ((recv_len = recvfrom(sock, recv_str, MAX_LEN, 0, 
         (struct sockaddr*)&from_addr, &from_len)) < 0) {
      perror("recvfrom() failed");
      exit(1);
    }

    /* output received string */
    /* Instead of stdout, i send the message to the user by bubble notify */

    /* Enable for debug */
    //printf("Received %d bytes from %s: ", recv_len, inet_ntoa(from_addr.sin_addr));
    
    /* Compare the sender-ip with the one we specified we are listening for */
    i = strcmp( inet_ntoa(from_addr.sin_addr), sender );

    if ( i == 0 ) {
      sprintf(buf,"%s%s",str1, recv_str);
      system(buf);
    }
    
  }

  /* send a DROP MEMBERSHIP message via setsockopt */
  if ((setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, 
       (void*) &mc_req, sizeof(mc_req))) < 0) {
    perror("setsockopt() failed");
    exit(1);
  }

  close(sock);  
}
_______________________________________________
Talking mailing list
Talking@ml.linuxvar.it
http://ml.linuxvar.it/cgi-bin/mailman/listinfo/talking