#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define RETRIAL_INTERVAL 1
#define RETRIAL_TIME 100
int main(int argc,char *argv[])
{
  int sock;
  struct sockaddr_in server,myserver;
  struct hostent *hp;
  struct sockaddr incoming_server;
  char buf[1024];
  int rval;
  int i,j,k,tmp;
  socklen_t from_len;

  fd_set setForSelect;
  struct timeval tv;

  /*printf("Argc:%d\n",argc);*/
  if (argc<4) { printf("ERROR: too few arguements");return 1;};

//create a socket
  sock=socket(AF_INET,SOCK_DGRAM,0);
  if (sock<0)
  {
	printf("ERROR:opening stream socket\n");
	return 1;
  }


//get the remote host name
  server.sin_family=AF_INET;
  hp=gethostbyname(argv[1]);
  if (hp==0)
  {
	printf("ERROR: %s:unknown host\n",argv[1]);
	return 2;
  }

  memcpy((char *)&server.sin_addr,(char *)hp->h_addr,hp->h_length);
  server.sin_port=htons(atoi(argv[2]));
  
  for (i=0;i<RETRIAL_TIME;i++)
//The client will try to send packets 5 times
  {
	  /*printf("to ");
	  printAddress((struct sockaddr *)&server);
	  */
	  

//creating a message	  
	  j=0;k=0;
	  for (j=3;j<argc;j++)
	  {
	    tmp=sprintf((&(buf[k])),"%s", argv[j]);k+=tmp;
	    if (j<(argc-1)) 
	    {
	    	tmp=sprintf((&(buf[k]))," "); 
	    	k+=tmp;
	    };
	  };
	//  tmp=sprintf((&(buf[k])),"\n");
	//  k+=tmp;
	  
//send the message
	  printf("Sending for the %d time:%s...\n",i,buf);
	  rval=sendto(sock,buf,k,0,(struct sockaddr *)&server,sizeof server);
	  /*printf("%d sent\n",rval);*/
	      
	  memset(buf,0,sizeof buf);  
	  from_len=sizeof incoming_server;	  
	  
//wait for reply, time out is 5 seconds
    	 FD_ZERO(&setForSelect);   	 
   	 FD_SET(sock,&setForSelect);
   	 
   	 tv.tv_sec=RETRIAL_INTERVAL;
   	 tv.tv_usec=0;
   	   	 
   	 select(sock+1,&setForSelect,0,0,&tv);
   	 
 	 if FD_ISSET(sock,&setForSelect)
 	 {	  
 	  /*printf("Reading...\n");	  */
//Get reply
	  rval=recvfrom(sock,buf,sizeof buf,0,(struct sockaddr *)&incoming_server,&from_len);
	  if (rval<0)
		 printf("ERROR:reading on stream socket\n");
	  else
	      printf("Received %d characters: %s\n",rval,buf);
	  
	  i=6;
	 }
	 else
	 {
	 	printf("no response:( \n");
	 }
  };  
  return 0;
}

void printAddress(struct sockaddr * saddr)
{
    struct sockaddr_in* addr=(struct sockaddr_in*) saddr;
    uint32_t a=addr->sin_addr.s_addr;
    unsigned a1,a2,a3,a4;
    a1=a%256;    a=a/256;    
    a2=a%256;    a=a/256;    
    a3=a%256;    a=a/256;    
    a4=a%256;    
    printf("%d %d %d %d : %d\n",a1,a2,a3,a4,addr->sin_port);
};

