Beginnings of network support.

TODO: rewrite to be addressfamily-independent.  (getaddrinfo)
This commit is contained in:
Steinar Hamre 2008-10-03 16:54:59 +00:00
parent 08dc193e53
commit 788724b4ff
2 changed files with 87 additions and 0 deletions

1
src/Makefile Normal file
View File

@ -0,0 +1 @@
CFLAGS=-g -std=c99

86
src/net.c Normal file
View File

@ -0,0 +1,86 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_CLIENTS 2
#define SRV_FDS 1
int servsock;
struct pollfd pollfds[SRV_FDS+MAX_CLIENTS];
int nclients = 0;
int
errx(int eval, const char *fmt, ...) {
va_list ap;
vfprintf(stderr, fmt, ap);
exit(eval);
}
int
net_server(int port) {
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(port);
servsock=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (servsock<0)
errx(1, "socket: %s", strerror(errno));
if (bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
errx(1, "bind port %d: %s", port, strerror(errno));
if (listen(servsock, 10) < 0)
errx(1, "listen: %s", strerror(errno));
pollfds[0].fd=servsock;
pollfds[0].events=POLLIN|POLLERR|POLLHUP;
for (int i=SRV_FDS; i<(SRV_FDS+MAX_CLIENTS); i++) {
pollfds[0].fd=-1;
pollfds[0].events=0;
}
}
int
net_poll() {
int npoll;
npoll=poll(pollfds, SRV_FDS+MAX_CLIENTS, -1);
if (npoll<0)
errx(1, "poll: %s", strerror(errno));
if (pollfds[0].revents) {
struct sockaddr_in clientaddr;
int cfd;
socklen_t slen;
cfd=accept(servsock, (struct sockaddr *)&clientaddr, &slen);
if (cfd<0)
errx(1, "accept: %s", strerror(errno));
// FIXME log, shout, or something
if (nclients>MAX_CLIENTS) {
#define STR_SERVER_FULL "Sorry, the server is full"
write(cfd, STR_SERVER_FULL, sizeof(STR_SERVER_FULL)-1);
close(cfd);
} else {
int i;
for (i=SRV_FDS; i<(SRV_FDS+MAX_CLIENTS); i++)
if (pollfds[i].fd=-1) break;
pollfds[i].fd=cfd;
pollfds[i].events=POLLIN|POLLERR|POLLHUP;
nclients++;
}
npoll--;
}
for (int i=SRV_FDS; npoll && i<(SRV_FDS+MAX_CLIENTS); i++) {
if (pollfds[SRV_FDS+i].revents) {
int n;
char buf[100];
n=read(pollfds[SRV_FDS+i].fd, &buf, sizeof(buf));
// parse buf
// handle disconnections
}
}
}