/* Author: Pete Broadwell
           Grinnell College

   This program simulates a scenario of the readers-writers program in which
   multiple readers (clients) and a single writer (server) communicate through
   a datagram socket. This is the processing for each client/reader.

*/

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>   /* socket command libraries needed by some compilers */
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>

#define SIM_LENGTH 6 /* number of integers to be written and read */
#define PORT 1229 /* local port on which the server establishes connection */

/* procedure to remove socket file and exit */
void clean_up(int cond, int *sock)
{ printf("Exiting now.\n");
  close(*sock);
  exit(cond);
} /* end of clean_up */

int main(int argc, char *argv[])
{ /* processing for client */
  int sock; /* socket file descriptor */
  struct sockaddr_in cli_name; /* socket address structure */
  int value; /* variable for number read from socket */
  size_t len; /* variable for the size of the cli_name structure */
  int client_id; /* variable for client's number as assigned by server */
  int count;
  char msg[20]; /* array for message to be written to socket */

  /* set the socket descriptor */
  sock = socket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0)
    { perror("Opening channel");
      clean_up(1, &sock);
    }

  /* set the physical address (cli_name) of the socket descriptor */
  bzero(&cli_name, sizeof(cli_name));
  cli_name.sin_family = AF_INET;
  cli_name.sin_addr.s_addr = inet_addr(argv[1]);
  cli_name.sin_port = htons(PORT);

  sleep(1); /* give server time to create the socket */

  printf("Client is alive.\n");

  /* initialize the msg array */
  for (count = 0; count < 20; count++)
    msg[count] = 0;

  /* write greeting to the socket */
  len = sizeof(cli_name);
  strcpy(msg, "Hello, server");
  
  sendto(sock, &msg, 20, 0, (struct sockaddr *)&cli_name, len);

  printf("Client has sent  %s  to socket.\n", msg);

  /* read identification number from socket */
  recvfrom(sock, &client_id, 4, 0, (struct sockaddr *)&cli_name, &len);
  printf("Client %d has received ID from server.\n", client_id);

  /* read integers from socket */
  for (count = 0; count < SIM_LENGTH; count++)
    { recvfrom(sock, &value, 4, 0, (struct sockaddr *)&cli_name, &len);
      printf("Client %d has received %d from socket.\n", client_id, value);
    }
  printf("Client %d done.\n", client_id);
  close(sock); /* close connection to socket */
  exit(0); /* exit with no errors */

} /* end of main */
