|
CS473 - Computer Networks
| Displaying exercises/e7/solution/egg.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 <sys/epoll.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <netdb.h>
#include <time.h>
#include <sys/utsname.h>
#define K 1024
#define min(a,b) ((a) < (b)? (a) : (b))
/*
* LOOK %d,%d
*/
int parse(char *s, int *x, int *y)
{
char *w;
w = strtok(s, " \r\n");
if (w == NULL) return 0;
if (strcasecmp("LOOK", w) != 0) return 0;
w = strtok(NULL, " ,\r\n");
if (w == NULL) return 0;
*x = atoi(w);
w = strtok(NULL, " ,\r\n");
if (w == NULL) return 0;
*y = atoi(w);
return 1;
}
int main(int argc, char *argv[])
{
FILE *eggs;
struct epoll_event epv;
struct sockaddr_in server, client;
socklen_t clientlen;
int sock, so = 1, port, epfd, r, i, j;
char buf[K], board[K][K];
if (argc < 2) {
fprintf(stderr,"Usage: egg <port>\n");
exit(0);
}
daemon(1,0);
srand(time(0));
port = atoi(argv[1]);
if (port < 47300 || port > 47350) {
fprintf(stderr,"Invalid port %d\n", port);
exit(1);
}
for(i=0; i < K; i++) {
for(j=0;j < K; j++) {
board[i][j] = 0;
}
}
sprintf(buf, "eggs.%d", port);
if ((eggs = fopen(buf, "w")) == NULL) {
fprintf(stderr,"Unable to open egg logfile for writing.\n");
exit(1);
}
for(r=0; r < 10; r++) {
do {
i = rand() % K;
j = rand() % K;
} while (board[i][j] == 1);
board[i][j] = 1;
fprintf(eggs,"%d,%d\n", i, j);
}
fclose(eggs);
// Create a SOCK_STREAM internet socket here:
sock = socket(AF_INET, SOCK_DGRAM, 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);
}
if ((epfd = epoll_create(25)) < 0) {
perror("epoll_create");
exit(1);
}
epv.events = EPOLLIN | EPOLLERR | EPOLLHUP;
epv.data.fd = -1;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &epv);
for(;;) {
r = epoll_wait(epfd, &epv, 1, -1);
if (r <= 0) continue;
if (epv.events & (EPOLLERR | EPOLLHUP)) break;
r = recvfrom(sock, buf, K, 0, (struct sockaddr *)&client,
&clientlen);
buf[min(r,K-1)] = '\0';
if (parse(buf, &i, &j)) {
r = rand() % 4;
if (r == 0) {
if (board[i][j]) sprintf(buf,"%d,%d: Found one!", i, j);
else sprintf(buf, "%d,%d: No egg.", i, j);
sendto(sock, buf, strlen(buf)+1, 0, (struct sockaddr *)&client,
sizeof(struct sockaddr_in));
}
}
}
// Not reached:
return 0;
}
|