Interactive Client

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

void interact(int r, int w)
{ char inp[1030];
  while (1)
  { fd_set files;
    FD_ZERO(&files);
    FD_SET(0, &files);   // 0 for stdin
    FD_SET(r, &files);
    timeval timeout = { 0, 30000 };  // seconds then microseconds
    int n=select(r+1,    // biggest file number set, plus one
                 &files, // fd_set for input files
                 NULL,   // fd_set for output files
                 NULL,   // fd_set for internet sockets gone peculiar
                 &timeout);
             // result n is number of ready file numbers, fd_sets are modified
             // so only ready ones are still set
    if (n>0)
    { if (FD_ISSET(0, &files))
      { int n=read(0, inp, 1024);
        if (n<=0) break;
        write(w, inp, n); }
      else if (FD_ISSET(r, &files))
      { int n=read(r, inp, 1024);
        if (n<=0) break;
        write(1, inp, n); /* 1 for stdout */ } } } }

void main(int argc, char *argv[])
{ if (argc!=3)
  { fprintf(stderr, "usage: %s remote-host port-number\n", argv[0]);
    exit(1); }
  char server_name[1000];
  strcpy(server_name, argv[1]);
  int port_number;
  int n=sscanf(argv[2], "%d", &port_number);
  if (n!=1)
  { fprintf(stderr, "\"%s\" is not a valid port number\n", argv[2]);
    exit(1); }

  struct hostent * server_info=gethostbyname(server_name);
  if (server_info==NULL)
  { fprintf(stderr, "(1) host \"%s\" not known\n", server_name); 
    exit(1); }
  struct in_addr * server_addr=(struct in_addr *)server_info->h_addr;
  if (server_addr->s_addr==NULL)
  { fprintf(stderr,"(2) host %s not known\n", inet_ntoa(*server_addr)); 
    exit(1); }

  struct sockaddr_in connection_descr;
  bzero(&connection_descr, sizeof(connection_descr));
  connection_descr.sin_family=AF_INET;
  connection_descr.sin_addr.s_addr=server_addr->s_addr;
  connection_descr.sin_port=htons(port_number);

  int sock=socket(AF_INET, SOCK_STREAM, 0);
  if (sock<0)
  { perror("socket failure");
    exit(1); }

  printf("\n[Connecting to %s (%s) on port %d]\n",
          server_name, inet_ntoa(*server_addr), port_number);

  n=connect(sock, (sockaddr *)&connection_descr, sizeof(connection_descr));
  if (n<0)
  { perror("connect");
    exit(1); }

  interact(sock, sock);

  close(sock);

  printf("[finished]\n"); }