#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>

int perreur(char *s)
{
  perror( s );
  exit( 1 );
}

#define   MAX 1024
int       SEND = 0, RECEPT = 0, TTL=1;
short int PORT = 31415;
in_addr_t UNICAST;
int       REUSE=0;
unsigned int LEN = 16;

//mark=args
int args(int argc, char* argv[])
{
  char *optliste = "a:p:r:s:t:uh";
  int   opt;
  while ( ( opt = getopt(argc, argv, optliste )) >=0 ) {
	    switch ( opt ){
	    case 'a' : UNICAST  = inet_addr(optarg); break;
	    case 's' : SEND   = atoi(optarg);        break;
            case 'r' : RECEPT = atoi(optarg);        break; 
	    case 't' : TTL =    atoi(optarg);        break;
	    case 'p' : PORT   = atoi(optarg);        break;
            case 'u' : REUSE = 1;                    break;
	    case 'h' : printf("\nusage %s : %s", argv[0], optliste);
	    default  : return 0;
	    }
	  }
return 1;
}
//mark=emission
//kwds=setsockopt
void  emission( int sock )
{  char bfr[ MAX ]="  unicast !\n";
   struct sockaddr_in adr;
// destination
   memset( & adr, 0, sizeof( struct sockaddr_in) );  
   adr.sin_family       = AF_INET;
   adr.sin_addr.s_addr  = UNICAST;
   adr.sin_port         = htons(PORT); 
   while ( SEND-- ) {
     bfr[0] = '0'+SEND;
     if ( sendto(sock, bfr, MAX, 0, (struct sockaddr *)&adr, LEN ) < 0 )
      perreur("emission");
     printf("%d", SEND);
     fflush(stdout);
     sleep(1);
  }
}
//mark=reception
//kwds=setsockopt
void  reception( int sock )                                                
{ char bfr[ MAX ];
  int  nb;
  struct sockaddr_in adr;
 
// assignation
  memset( & adr, 0, sizeof( struct sockaddr_in) );  
  adr.sin_family       = AF_INET;
  adr.sin_addr.s_addr  = UNICAST;//htonl(INADDR_ANY);
  adr.sin_port         = htons(PORT);
// plusieurs processus entre par sock :
  if ( setsockopt( sock , SOL_SOCKET, SO_REUSEADDR, &REUSE, sizeof(REUSE)) < 0 )
   perreur("reusing problem");
  if ( bind(sock,  (struct sockaddr*) & adr, LEN ) < 0 )
    perreur("bind");
  while ( RECEPT-- ) {
      nb = recvfrom(sock, bfr, MAX, 0, (struct sockaddr *)& adr, &LEN);
      if ( nb > 0 ) {
         printf("%s", bfr);
      }
  }
}
//mark=main
//kwds=reception, emission
int  main( int argc, char* argv[] )                                         
{ 
  int sock;
  if ( (sock = socket(PF_INET, SOCK_DGRAM, 0 )) < 0  )
    perreur("socket");
  //adresse par defaut
  UNICAST = inet_addr("192.168.0.105");
  if ( ! args( argc, argv ) ) exit( 1 ); 

  if ( RECEPT ) reception( sock);
  if ( SEND   )  emission( sock); 
  
  close(sock);
  return 0;
}
// cut
