Network code updated. (simplest solution possible)

It works!
This commit is contained in:
Steinar Hamre 2008-10-09 21:10:35 +00:00
parent ea727f335a
commit c606818adc
2 changed files with 115 additions and 19 deletions

130
src/net.c
View File

@ -32,6 +32,16 @@ errx(int eval, const char *fmt, ...) {
exit(eval);
}
struct file {
int fd;
char ibuf[BUFSIZ];
char obuf[BUFSIZ];
int istart;
int iend;
int oend;
} sfile[2];
void
net_server(int port) {
struct sockaddr_in serveraddr;
@ -44,34 +54,30 @@ net_server(int port) {
if (servsock<0)
errx(1, "socket: %s\n", strerror(errno));
int r;
do r=bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
while ((r<0) && (errno==EADDRINUSE));
do {
r=bind(servsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
serveraddr.sin_port = htons(port++);
} while ((r<0) && (errno==EADDRINUSE));
if (r < 0)
errx(1, "bind port %d: %s\n", port, strerror(errno));
if (listen(servsock, 10) < 0)
errx(1, "listen: %s\n", strerror(errno));
#if 1
// FIXME Temporary startup. Use net_poll for this later:
printf("Waiting for connections...\n");
printf("Waiting for connections on port %d...\n", port-1);
for (int i=0; i<2; i++) {
struct sockaddr_in clientaddr;
int cfd;
socklen_t slen;
FILE *f;
cfd=accept(servsock, (struct sockaddr *)&clientaddr, &slen);
if (cfd<0)
errx(1, "accept: %s\n", strerror(errno));
// FIXME log, shout, or something
printf("client log on...\n");
f = fdopen(cfd, "r+");
if (!f)
errx(1, "fdopen: %s\n", strerror(errno));
setlinebuf(f);
fprintf(f, "Welcome!\n");
sfile[i].fd=cfd;
net_side_printf(i, "Welcome!\n");
if (i==0)
fprintf(f, "Waiting for another player...\n");
fflush(f);
net_side[i]=f;
net_side_printf(i, "Waiting for another player...\n");
}
net_all_printf("Starting game\n");
#else
@ -84,10 +90,102 @@ net_server(int port) {
#endif
}
#if 1
int
net_getc(int side) {
char c;
int n;
assert(side==0 || side==1);
n=read(sfile[side].fd, &c, 1);
if (n<0) return -1;
return c;
}
void
net_all_flush() {
}
void
net_side_printf(int side, const char *fmt, ...) {
va_list ap;
char buf[BUFSIZ];
int len, n;
assert((side==0) || (side==1));
va_start(ap, fmt);
len=vsnprintf(buf, sizeof(buf)-1, fmt, ap);
va_end(ap);
if (len > BUFSIZ-1)
errx(1, "BUFSIZ too small\n");
char *bufp=buf;
do {
n=write(sfile[side].fd, bufp, len);
if (n<0)
errx(1, "write: %s\n", strerror(errno));
bufp+=n;
} while (bufp < buf+len);
}
void
net_all_printf(const char *fmt, ...) {
va_list ap;
char buf[BUFSIZ];
int len, n;
va_start(ap, fmt);
len=vsnprintf(buf, sizeof(buf)-1, fmt, ap);
va_end(ap);
if (len > BUFSIZ-1)
errx(1, "BUFSIZ too small\n");
for (int side=0; side<2; side++) {
char *bufp=buf;
do {
n=write(sfile[side].fd, bufp, len);
if (n<0)
errx(1, "write: %s\n", strerror(errno));
bufp+=n;
} while (bufp < buf+len);
}
}
#else
#define net_getc2(f) (f.iend<BUFSIZ||net_fillbuf(f), f.ibuf[f.iend++])
#define net_getc(side) net_getc2(sfile[side])
void
net_fillbuf(struct file f) {
n=read(f.fd, f.ibuf, BUFSIZ);
if (n==0)
errx(1, "end of file\n");
if (n<0)
errx(1, "read: %s\n", strerror(errno));
f.iend=n;
}
void
net_side_flush(int side) {
start=0;
do start+=write(fd[side], obuf[side]+start, obufend);
while (start < obufend);
}
void
net_all_flush() {
for (int i=0; i<2; i++)
fflush(net_side[i]);
net_side_flush(i);
}
static void
net_side_vprintf(int side, const char *fmt, va_list ap) {
n=vsnprintf(obuf[side], BUFSIZ-obufend, fmt, ap);
if (n > (BUFSIZ-obufend-1)) {
if (n > BUFSIZ-1)
errx(1, "BUFSIZ too small\n");
net_side_flush(side);
n=vsnprintf(obuf[side], BUFSIZ-obufend, fmt, ap);
}
obufend[side]+=n;
}
void
@ -95,7 +193,7 @@ net_all_printf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
for (int i=0; i<2; i++)
vfprintf(net_side[i], fmt, ap);
net_side_vprintf(i, fmt, ap);
va_end(ap);
}
@ -104,10 +202,10 @@ net_side_printf(int side, const char *fmt, ...) {
va_list ap;
assert((side==0) || (side==1));
va_start(ap, fmt);
vfprintf(net_side[side], fmt, ap);
net_side_vprintf(side, fmt, ap);
va_end(ap);
}
#endif
void

View File

@ -5,12 +5,10 @@
#include <stdio.h>
extern FILE *net_side[2];
#define net_getc(side) getc(net_side[i])
extern void net_server(int port);
extern int net_getc(int side);
extern void net_all_printf(const char *fmt, ...);
extern void net_side_printf(int side, const char *fmt, ...);
extern void net_all_flush();