Lecture Notes for Client-Server Interfaces

19 February 2004 - Concurrency and Processor Performance


The Objectives


The Environment


The Client

static void tcp_echo(
  char * host, char * service, 
  unsigned size, unsigned iters)

  char * str = new char[size]
  char * bfr = new char[size]

  for (unsigned i = 0; i < iters; i++)

    gettimeofday(&start, NULL)

    int s = tcp_connect(host, service)

    write(s, str, size)
    tcp_read(s, bfr, size)

    shutdown(s, 1)
    close(s)

    gettimeofday(&stop, NULL)


An Iterative Server

const unsigned buffer_size = 1024*16;
static char buffer[buffer_size];

static void echo(int s)

  int cc

  do
    cc = read(s, buffer, sizeof(buffer))
    write(s, buffer, cc)
  while cc > 0


int main(int argc, char * argv[]) 

  const int ms = passive_tcp(port, tcp_qlen)

  while true
    const int s = accept_tcp(ms)
    echo(s)
    close(s)

  return EXIT_SUCCESS


The Results


The Results Continued


Comments


A Forking Server

const unsigned buffer_size = 1024*16;
static char buffer[buffer_size];

static void echo(int s)
  int cc
  while cc = read(s, buffer, sizeof(buffer)) > 0
    write(s, buffer, cc)
  close(s)


int main(int argc, char * argv[])

  const int ms = passive_tcp(port, tcp_qlen)

  if signal(SIGCHLD, SIG_IGN) == SIG_ERR
    errexit("signal(sigchld) failed:")

  while true
    int ss = accept_tcp(ms)
    switch fork()
      case 0:  close(ms)
               echo(ss)
               return EXIT_SUCCESS
      default: close(ss)
               break

  return EXIT_SUCCESS


The Results


The Results Continued