#include <errno.h>       /* for perror                            */
#include <netdb.h>       /* for gethostbyname                     */
#include <netinet/in.h>  /* for sockaddr_in, INADDR_ANY           */
#include <stdlib.h>      /* for atoi, exit                        */
#include <stdio.h>       /* for fprintf, perror                   */
#include <string.h>      /* for memcpy                            */
#include <sys/socket.h>  /* for socket, bind, socklen_t, recvfrom */
                         /*     AF_INET, SOCK_DGRAM               */
#include <sys/types.h>   /* for socket, bind, uint16_t, ssize_t   */
#include <unistd.h>      /* for read, write, close                */


#define BLKSIZE  1024

void main(int argc, char *argv[])
/*
 *  This is a client test of UDP. 
 *  It reads a file from stdin in blocks of size BLKSIZE
 *  and outputs the blocks to the connection.
 */
{
    uint16_t port;
    int sock;
    struct sockaddr_in server;
    struct hostent *hp;

    ssize_t bytesread;
    ssize_t byteswritten;
    char buf[BLKSIZE];
       
    if (argc != 3) {
        fprintf(stderr, "Usage: %s host port\n", argv[0]);
        exit(1);
    }

       /* set up the address to the server to be included in datagram */
   server.sin_family = AF_INET;
   port = (uint16_t)atoi(argv[2]); 
   server.sin_port = htons(port);
   if (!(hp = gethostbyname(argv[1]))) {
      perror("Unable to get host byname");   
      exit(1); 
   }
   memcpy((char *)&server.sin_addr, hp->h_addr_list[0], hp->h_length);

                  /* create a socket for sending datagrams */
   if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
      perror("Unable to create socket");
      exit(1);
   } 

   for ( ; ; ) {
      bytesread = read(STDIN_FILENO, buf, BLKSIZE);
      if ( (bytesread == -1) && (errno == EINTR) )
         fprintf(stderr, "Client restarting read\n");
      else if (bytesread <= 0) 
         break;
      else {
         byteswritten = sendto(sock, buf, bytesread, 0, (struct sockaddr *)&server, sizeof(server));
         if (byteswritten != bytesread) {
            fprintf(stderr, "Error writing %ld bytes, %ld bytes written\n",
                (long)bytesread, (long)byteswritten);
            break;
         }
      }
   }
   close(sock);
   exit(0);
}

