/* 
 * Example of master using TCP protocol.
 * Reference: W. Richard Stevens. "UNIX Network Programming". 
 *            Prentice Hall Software Series. 1990.
 *            Chapter 6: Berkeley Sockets.
 */


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

#define HOST_ADDR_SIZE 15
#define NUM_HOSTS      2
#define REQ_SIZE       100
#define RES_SIZE       100
#define SERV_HOST1_ADDR "150.164.3.10"   /* host addr for slave 1 */
#define SERV_HOST2_ADDR "150.164.3.12"   /* host addr for slave 2 */
#define SERV_TCP_PORT  1024

/***********************************************/
/* Function: main */
/**********************************************/
int main(int argc, char *argv[]){    
  fd_set activefdSet;  
  char addr[NUM_HOSTS][HOST_ADDR_SIZE];
  int nresults;
  int procId;
  char request[REQ_SIZE];
  char response[RES_SIZE];
  struct sockaddr_in serv_addr;
  int sockfd[NUM_HOSTS];    

  /* 
   * Set host addresses.
   */
  strcpy(addr[0],SERV_HOST1_ADDR);
  strcpy(addr[1],SERV_HOST2_ADDR);
  for (procId=0;procId<NUM_HOSTS;procId++){
    /*
     * Fill in the structure "serv_addr" with the address of the 
     * slave that we want to connect with.
     */  
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(addr[procId]);
    serv_addr.sin_port = htons(SERV_TCP_PORT);  
    /*
     * Open a TCP socket (an Internet stream socket).
     */  
    if ( (sockfd[procId] = socket(AF_INET, SOCK_STREAM, 0)) < 0){
      fprintf(stderr,"master: can't open stream socket\n");
    }
    /* 
     * Connect to the slave.
     */
    if (connect(sockfd[procId], (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
      fprintf(stderr,"master: can't connect to slave\n");
    }
  }
  for (procId=0;procId<NUM_HOSTS;procId++){
    /* 
     * Send the request to the slave. 
     */
    strcpy(request,"teste");
    if (send(sockfd[procId], (void *)request, REQ_SIZE, MSG_NOSIGNAL) < 0){
      fprintf(stderr,"master: can't send request\n");    
      close(sockfd[procId]);
      exit(1);
    }  
  } 
  FD_ZERO(&activefdSet);
  for (procId=0;procId<NUM_HOSTS;procId++){
    FD_SET(sockfd[procId], &activefdSet);
  }  
  nresults=0;
  while (nresults<NUM_HOSTS){
    fd_set readfdSet = activefdSet;
    int retval = select(FD_SETSIZE, &readfdSet, NULL, NULL, NULL);
    if (retval < 0){
      fprintf(stderr,"master: error on select\n");
      exit(1);
    }
    for (procId=0;procId<NUM_HOSTS;procId++){
      if (FD_ISSET(sockfd[procId], &readfdSet)){
        /* 
         * Receive the response from the slave. 
         */
        if (recv(sockfd[procId], (void *)response, RES_SIZE,MSG_WAITALL|MSG_NOSIGNAL) < 0){
	  fprintf(stderr,"master: can't receive response\n");    
	  close(sockfd[procId]);
	  exit(1);
        }
        printf("master: response= %s \n",response);
        nresults++;
      }
    }
  }
  for (procId=0;procId<NUM_HOSTS;procId++){
    close(sockfd[procId]);
  }
  return(0);
}
