Logo  

CS473 - Computer Networks

Displaying exercises/e5/solution/serv.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <netdb.h>
#include <time.h>
#include <sys/utsname.h>

#define K	1024

#define PORT	47350 // Your PORT # (5 digits of your username)

/* serv.c:
 *   A program to establish a server that opens and sends a file to a client.
 */

void handle(int sock, char *file)
{
  char buf[K];
  int fd, r;
  
  // Open file <file> for reading only:
  // If it fails and print an error message and return;
  if ((fd = open(file, O_RDONLY)) < 0) {
    fprintf(stderr,"Unable to open file for reading.\n");
    return;
  }
  // Make a loop to read a K sized buffer of data from the file
  // and send that to the client on the client socket, repeat
  // until the end of file is reached.
  while((r = read(fd, buf, K)) > 0) {
    if (write(sock, buf, r) < 0) break;
  }
  // Close file descriptor:
  close(fd);
}

int main(int argc, char *argv[])
{
  struct sockaddr_in server;
  int sock, msgsock, so = 1;

  if (argc < 2) {
    fprintf(stderr,"Usage: serv <file>\n");
    exit(0);
  }

  // Create a SOCK_STREAM internet socket here:
  sock = socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0) {
    perror("socket");
    exit(1);
  }

  // Set the socket option SO_REUSEADDR here:
  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so));

  // Setup server address, bind to any address on port defined by the PORT
  // #define above:

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = htons(PORT);
  if (bind(sock, (struct sockaddr *)&server, sizeof(server))) {
    perror("bind");
    exit(1);
  }

  // Start listening for connections:
  if (listen(sock, 5) < 0) {
    perror("listen");
    exit(1);
  }

  for(;;) {
    // Accept a connection here, store the new descriptor in msgsock:
    msgsock = accept(sock, NULL, NULL);
    if (msgsock < 0) {
      perror("accept");
      continue;
    }
    handle(msgsock, argv[1]);
    close(msgsock);
  }
  // Not reached:
  return 0;
}