Logo  

CS473 - Computer Networks

Displaying exercises/e7/solution/hunt.c

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

#define K	1024

void advance(int map[K][K], int *x, int *y)
{
  do {
    *x = (*x + 1) % K;
    if (*x == 0) {
      *y = (*y + 1) % K;
    }
  } while(map[*x][*y]);
}

int main(int argc, char *argv[])
{
  struct epoll_event epv;
  struct sockaddr_in server;
  struct hostent *hp;
  int sock, epfd, r, x, y, i, j, found = 0, map[K][K];
  char *w, msg[K];
  
  if (argc < 3) {
    fprintf(stderr,"Usage: inetdgram_c <host> <port#>\n");
    exit(0);
  }

  for(x=0; x < K; x++) {
    for(y=0; y < K; y++) {
      map[x][y] = 0;
    }
  }

  /* Create socket on which to send. */
  sock = socket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    perror("opening datagram socket");
    exit(1);
  }

  /*
   * Construct name, with no wildcards, of the socket to send to.
   * Gethostbyname() returns a structure including the network address
   * of the specified host. The port number is taken from the command
   * line.
   */
  hp = gethostbyname(argv[1]);
  if (hp == NULL) {
    fprintf(stderr, "%s: unknown host", argv[1]);
    exit(2);
  }
  memcpy(&server.sin_addr.s_addr, hp->h_addr, hp->h_length);
  server.sin_family = AF_INET;
  server.sin_port = htons(atoi(argv[2]));

  if ((epfd = epoll_create(25)) < 0) {
    perror("epoll_create");
    exit(1);
  }
  epv.events = EPOLLIN | EPOLLOUT;
  epv.data.fd = -1;
  epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &epv);

  /* Look for eggs: */
  x = y = 0;
  while(found < 10) {
    r = epoll_wait(epfd, &epv, 1, -1);
    if (r <= 0) continue;

    if (epv.events & (EPOLLERR | EPOLLHUP)) {
      fprintf(stderr,"Error on socket!\n");
      break;
    }
    if (epv.events & EPOLLOUT) {
      sprintf(msg, "LOOK %d,%d", x, y);
      advance(map, &x, &y);
      sendto(sock, msg, strlen(msg)+1, 0, (struct sockaddr *)&server,
	     sizeof(struct sockaddr_in));
    }
    if (epv.events & EPOLLIN) {
      if ((r = read(sock, msg, sizeof(msg))) > 0) {
	if ((w = strtok(msg, ",: ")) == NULL) continue;
	i = atoi(w);
	if ((w = strtok(NULL, ",: ")) == NULL) continue;
	j = atoi(w);
	if ((w = strtok(NULL, ",: ")) == NULL) continue;
	map[i][j] = 1;
	if (strcasecmp(w, "Found") == 0) {
	  printf("Found an egg at %d,%d\n", i, j);
	  found++;
	}
      }
    }
  }
  close(sock);
}