April 1997
- From out of the shadows... Dan Mazeau
- Introduction Shawn Halpenny
- Introduction Nathan Yospe
- Introduction Chris Gray
- Introduction coder@ibm.net
- Introduction S001GMU@nova.wright.edu
- Introduction Jeff Kesselman
- Introduction Chris Gray
- Introduction Mik Clarke
- Introduction Caliban Tiresias Darklock
- Introduction Mik Clarke
- Introduction Caliban Tiresias Darklock
- Introduction J C Lawrence
- Introduction Elia Morling
- Event-driven? Michael Hohensee
- Event-driven? Nathan Yospe
- Event-driven? coder@ibm.net
- Event-driven? Jon A. Lambert
- Event-driven? Adam Wiggins
- Event-driven? Shawn Halpenny
- Event-driven? Chris Gray
- Event-driven? coder@ibm.net
- (subject missing) Dan Mazeau
- A late introduction Jon A. Lambert
- Re-Introduction S001GMU@nova.wright.edu
- New guy Walter Goodwin
- New guy coder@ibm.net
- Socket Stuff Shawn Halpenny
- database stuff Chris Gray
- So in an event-driven server, how do you ... Michael Hohensee
- So in an event-driven server, how do you ... Nathan Yospe
- So in an event-driven server, how do you ... S001GMU@nova.wright.edu
- So in an event-driven server, how do you ... Chris Gray
:It looks like you guys hate polling. (Not that I blame you, I don't
:really like it myself. :) But if you've got a system that just sits
:until the next "ripening", how do you do your IO with players? Do you
:use an endless loop to poll the connections? Or do you use the SIGIO
:signal?
No, just use the BSD 'select' call. It simultaneously allows for a whole
mess of sockets, and a timeout. Here is more detail than you ever wanted
(its the entire 'main' from my ToyMUD system):
int
main(int argc, char *argv[])
{
struct sockaddr_in myAddr;
int hostPort;
Variable_t *globalContext;
hostPort = DEFAULT_PORT;
DbPath = DEFAULT_DB;
if (argc >= 2) {
hostPort = atoi(argv[1]);
if (argc >= 3) {
DbPath = argv[2];
}
}
Clients = NULL;
Actions = NULL;
PlayerCount = 0;
globalContext = readDB(DbPath);
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket < 0) {
perror("socket");
exit(1);
}
memset(&myAddr, 0, sizeof(struct sockaddr_in));
myAddr.sin_port = htons(hostPort);
if (bind(Socket, (struct sockaddr *) &myAddr,
sizeof(struct sockaddr_in)) < 0)
{
perror("bind");
exit(1);
}
if (listen(Socket, 5) < 0) {
perror("listen");
exit(1);
}
FD_ZERO(&AllPlayerBits);
initInterpreter(globalContext);
WantQuit = false;
CurrentDelay = MAX_DELAY;
LastTime = time(NULL);
srand(LastTime);
signal(SIGINT, interruptHandler);
#ifndef __SASC
signal(SIGPIPE, SIG_IGN);
#endif
startMachines();
while (! WantQuit || PlayerCount != 0) {
fd_set readFds, exceptFds;
struct sockaddr_in from;
Client_t *cl;
int res;
struct timeval timeval;
cleanupMachines();
readFds = AllPlayerBits;
FD_SET(Socket, &readFds);
exceptFds = readFds;
timeval.tv_sec = CurrentDelay;
timeval.tv_usec = 0;
res = select(FD_SETSIZE, &readFds, (fd_set *) NULL, &exceptFds,
&timeval);
if (res < 0) {
if (errno != EINTR) {
perror("select");
mudAbort(NULL);
}
WantQuit = true;
} else if (res == 0) {
doDelayedActions();
} else {
if (FD_ISSET(Socket, &exceptFds)) {
perror("select");
mudAbort(NULL);
}
if (FD_ISSET(Socket, &readFds)) {
int clientFd;
#ifdef __SASC
LONG fromLen;
#else
int fromLen;
#endif
fromLen = sizeof(struct sockaddr_in);
clientFd = accept(Socket, (struct sockaddr *) &from, &fromLen);
if (clientFd < 0) {
if (errno != EINTR) {
perror("accept");
mudAbort(NULL);
}
} else {
struct hostent *hp;
cl = (Client_t *) mudAlloc(sizeof(Client_t));
cl->cl_fd = clientFd;
hp = gethostbyaddr((const char *) &from,
sizeof(struct in_addr), AF_INET);
if (hp == NULL) {
sprintf(&PrintMessage[0], "%08lx",
from.sin_addr.s_addr);
} else {
strcpy(&PrintMessage[0], hp->h_name);
}
cl->cl_hostName = strdup(&PrintMessage[0]);
cl->cl_state = cs_name;
cl->cl_player = NULL;
cl->cl_next = Clients;
if (Clients != NULL) {
Clients->cl_prev = cl;
}
cl->cl_prev = NULL;
cl->cl_inputLength = 0;
cl->cl_exiting = false;
cl->cl_isMachine = false;
cl->cl_deleted = false;
Clients = cl;
PlayerCount += 1;
FD_SET(clientFd, &AllPlayerBits);
cprintf(cl, "Enter player name: ");
}
}
cl = Clients;
while (cl != NULL) {
Client_t *nextClient;
nextClient = cl->cl_next;
if (FD_ISSET(cl->cl_fd, &exceptFds)) {
if (cl->cl_state == cs_createQuery ||
cl->cl_state == cs_createPW1 ||
cl->cl_state == cs_createPW2)
{
deletePlayer(cl->cl_player);
cl->cl_player = NULL;
} else {
runWithPlayer(cl, cl->cl_player, "QUIT_ACTION");
}
killPlayer(cl);
} else if (FD_ISSET(cl->cl_fd, &readFds)) {
processInput(cl);
}
cl = nextClient;
}
doDelayedActions();
}
}
shutdown(Socket, 2);
writeDB(DbPath, getGlobals());
return(0);
}
Wheeeee!
Activity on the main socket, 'Socket', is only connection requests from
new clients. 'killPlayer' shutsdown the client. 'processInput' reads input
data from the client socket, and if full lines are found, processes them
as MUD commands (or program segments, since this MUD allows everyone to
program). This code runs on SunOS4, Solaris, AIX, HALOS, HP-UX and Amiga,
and probably more that I haven't personally tested. You *might* encounter
a non-BSD system that requires you to use 'poll' instead of 'select', but
you can mix'n'match with conditional compilation.
In AmigaMUD its a bit different, since its not UNIX, and there everything
is done via a slightly extended 'SelectWait' call, which combines the
normal 'select' call with the Amiga 'Wait' call, which waits for any
Amiga-style events, one of which is my MUD-event timer.
--
Chris Gray cg@ami-cg.GraySage.Edmonton.AB.CA - So in an event-driven server, how do you ... clawrenc@xsvr1.cup.hp.com
- So in an event-driven server, how do you ... clawrenc@cup.hp.com
- Off on the languages tangent! Chris Gray
- Yet Another Introduction Reed D. Copsey, Jr.
- Yet Another Introduction Nathan Yospe
- Yet Another Introduction clawrenc@cup.hp.com
- Yet Another Introduction clawrenc@cup.hp.com
- Yet Another Introduction Adam Wiggins
- Yet Another Introduction Dmitri Kondratiev
- self-intro: Cynbe Cynbe ru Taren
- Unique id's Chris Gray
- Unique id's clawrenc@cup.hp.com
- Unique id's Jon A. Lambert
- Unique id's coder@ibm.net
- Unique id's Jon A. Lambert
- Unique id's coder@ibm.net
- Unique id's Jeff Kesselman
- Unique id's clawrenc@cup.hp.com
- Unique id's Jon A. Lambert
- Dupes are my fault (again) coder@ibm.net
- six degrees of submission ... er, compilation. Cynbe ru Taren
- six degrees of submission ... er, compilation. Jeff Kesselman
- Java as a mudserver language Cynbe ru Taren
- Java as a mudserver language Jeff Kesselman
- Execution Chris Gray
- Using system time for ObjectIDs clawrenc@cup.hp.com
- short absence Chris Gray
- short absence coder@ibm.net
- Hello! Ross Nicoll
- Ho hum (clarifiyign AI terms) Jeff Kesselman
- Ho hum Ling
- Fw: Just a bit of musing Travis Casey
- Risk Assessment -- was (Ho hum) Jon A. Lambert
- Who is Steward and what can he do for me? Jon A. Lambert
- Who is Steward and what can he do for me? clawrenc@cup.hp.com
- Who is Steward and what can he do for me? Chris Gray
- project management (or coding, kings, and other things) Jon A. Lambert
- Threads and Sockets (Was Ho hum) S001GMU@nova.wright.edu
- Threads and Sockets (Was Ho hum) Jeff Kesselman
- Threads and Sockets (Was Ho hum) S001GMU@nova.wright.edu
- Threads and Sockets (Was Ho hum) clawrenc@cup.hp.com
- Threads and Sockets (Was Ho hum) Chris Gray
- Strings & Memory Usage Greg Munt
- Strings & Memory Usage clawrenc@cup.hp.com
- Strings & Memory Usage Jeff Kesselman
- Strings & Memory Usage Shawn Halpenny
- Strings & Memory Usage ashen
- Strings & Memory Usage Chris Gray
- Steward coder@ibm.net
- r.g.m.* - worthwhile thread Nathan Yospe
- r.g.m.* - worthwhile thread clawrenc@cup.hp.com
- r.g.m.* - worthwhile thread Jeff Kesselman
- r.g.m.* - worthwhile thread Chris Gray
- (fwd) A Mud Protocol (MUD Markup Language) coder@ibm.net
- Ho hum (Sockets) Ling
- Steward and other painful friends coder@ibm.net
- A Combat System (please critique!) S001GMU@nova.wright.edu
- Your Message To mud-dev Jon A. Lambert
- I'm back Chris Gray
- Changes to the list coder@ibm.net
- Oops coder@ibm.net
- Verb binding Chris Gray
- Verb binding clawrenc@cup.hp.com
- Verb binding ashen
- Verb binding Chris Gray
- Verb binding Adam Wiggins
- Verb binding clawrenc@cup.hp.com
- Verb binding S001GMU@nova.wright.edu
- Verb binding Shawn Halpenny
- Verb binding Chris Gray
- Verb binding clawrenc@cup.hp.com
- Verb binding Chris Gray
- Why have a combat state? Jeff Kesselman
- Why have a combat state? clawrenc@cup.hp.com
- Introduction Jamie Norrish
- Introduction S001GMU@nova.wright.edu
- Introduction clawrenc@cup.hp.com
- Introduction Jeff Kesselman
- Introduction clawrenc@cup.hp.com
- Introduction Chris Gray
- Introduction Travis Casey
- Introduction Jeff Kesselman
- Introduction scherecwich@angelfire.com
- Introduction Jon A. Lambert
- Introduction Chris Gray
- (fwd) Issues from the digests and Wout's list Raz
- (fwd) Issues from the digests and Wout's list Chris Gray
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Raz
- (fwd) Issues from the digests and Wout's list Chris Gray
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Chris Gray
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Oliver Jowett
- (fwd) Issues from the digests and Wout's list Chris Gray
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Raz
- (fwd) Issues from the digests and Wout's list Miroslav Silovic
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Adam Wiggins
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Miroslav Silovic
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list Raz
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- (fwd) Issues from the digests and Wout's list clawrenc@cup.hp.com
- Me Raz
- Sendmail changes coder@ibm.net
- Reposts Adam Wiggins
- Semaphores, Mutices, fd_sets Greg Munt
- Semaphores, Mutices, fd_sets Jeff Kesselman
- Semaphores, Mutices, fd_sets clawrenc@cup.hp.com
- MUD Design Digest V1 #55 coder@ibm.net
- Me Raz
- Magnetic Scrolls' magical parser Greg Munt
- Magnetic Scrolls' magical parser clawrenc@cup.hp.com
- Magnetic Scrolls' magical parser Adam Wiggins
- Magnetic Scrolls' magical parser Nathan Yospe
- Magnetic Scrolls' magical parser Chris Gray
- Magnetic Scrolls' magical parser Ling
- Magnetic Scrolls' magical parser Chris Gray
- Magnetic Scrolls' magical parser Shawn Halpenny
- Reposts Jeff Kesselman
- Email change Alex Oren
- SUBSCRIBE Alex Oren
- (fwd) Death in Muds -(also Birth, Imprisonment, Aging, and skill development) coder@ibm.net
- fd_set limitations Greg Munt
- parsing Chris Gray