<!-- MHonArc v2.4.4 --> <!--X-Subject: Re: So in an event-driven server, how do you ... --> <!--X-From-R13: ptNnzv-pt.UenlEntr.Sqzbagba.OP.QO (Quevf Uenl) --> <!--X-Date: from babe.globecomm.net [207.51.48.8] by mx01.ca.us.ibm.net id 860479703.201150-1 Tue Apr 8 06:08:23 1997 --> <!--X-Message-Id: 9704080205.7x11@ami-cg.GraySage.Edmonton.AB.CA --> <!--X-Content-Type: text/plain --> <!--X-Head-End--> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <html> <head> <title>MUD-Dev message, Re: So in an event-driven server, how do you ...</title> <!-- meta name="robots" content="noindex,nofollow" --> <link rev="made" href="mailto:cg#ami-cg,GraySage.Edmonton.AB.CA"> </head> <body background="/backgrounds/paperback.gif" bgcolor="#ffffff" text="#000000" link="#0000FF" alink="#FF0000" vlink="#006000"> <font size="+4" color="#804040"> <strong><em>MUD-Dev<br>mailing list archive</em></strong> </font> <br> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] <br clear=all><hr> <!--X-Body-Begin--> <!--X-User-Header--> <!--X-User-Header-End--> <!--X-TopPNI--> Date: [ <a href="msg00049.html">Previous</a> | <a href="msg00047.html">Next</a> ] Thread: [ <a href="msg00040.html">Previous</a> | <a href="msg00090.html">Next</a> ] Index: [ <A HREF="author.html#00046">Author</A> | <A HREF="#00046">Date</A> | <A HREF="thread.html#00046">Thread</A> ] <!--X-TopPNI-End--> <!--X-MsgBody--> <!--X-Subject-Header-Begin--> <H1>Re: So in an event-driven server, how do you ...</H1> <HR> <!--X-Subject-Header-End--> <!--X-Head-of-Message--> <UL> <LI><em>To</em>: <A HREF="mailto:mud-dev#null,net">mud-dev#null,net</A></LI> <LI><em>Subject</em>: Re: So in an event-driven server, how do you ...</LI> <LI><em>From</em>: <A HREF="mailto:cg#ami-cg,GraySage.Edmonton.AB.CA">cg#ami-cg,GraySage.Edmonton.AB.CA</A> (Chris Gray)</LI> <LI><em>Date</em>: Mon, 7 Apr 97 19:05:43 MST</LI> </UL> <!--X-Head-of-Message-End--> <!--X-Head-Body-Sep-Begin--> <HR> <!--X-Head-Body-Sep-End--> <!--X-Body-of-Message--> <PRE> :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 </PRE> <!--X-Body-of-Message-End--> <!--X-MsgBody-End--> <!--X-Follow-Ups--> <HR> <!--X-Follow-Ups-End--> <!--X-References--> <!--X-References-End--> <!--X-BotPNI--> <UL> <LI>Prev by Date: <STRONG><A HREF="msg00049.html">Off on the languages tangent!</A></STRONG> </LI> <LI>Next by Date: <STRONG><A HREF="msg00047.html">Re: Random thoughts</A></STRONG> </LI> <LI>Prev by thread: <STRONG><A HREF="msg00040.html">Re: So in an event-driven server, how do you ...</A></STRONG> </LI> <LI>Next by thread: <STRONG><A HREF="msg00090.html">Re: So in an event-driven server, how do you ...</A></STRONG> </LI> <LI>Index(es): <UL> <LI><A HREF="index.html#00046"><STRONG>Date</STRONG></A></LI> <LI><A HREF="thread.html#00046"><STRONG>Thread</STRONG></A></LI> </UL> </LI> </UL> <!--X-BotPNI-End--> <!--X-User-Footer--> <!--X-User-Footer-End--> <ul><li>Thread context: <BLOCKQUOTE><UL> <LI><strong><A NAME="00049" HREF="msg00049.html">Off on the languages tangent!</A></strong>, Chris Gray <a href="mailto:cg#ami-cg,GraySage.Edmonton.AB.CA">cg#ami-cg,GraySage.Edmonton.AB.CA</a>, Tue 08 Apr 1997, 13:07 GMT <LI><strong><A NAME="00038" HREF="msg00038.html">So in an event-driven server, how do you ...</A></strong>, Michael Hohensee <a href="mailto:michael#sparta,mainstream.net">michael#sparta,mainstream.net</a>, Tue 08 Apr 1997, 00:35 GMT <UL> <li><Possible follow-up(s)><br> <LI><strong><A NAME="00039" HREF="msg00039.html">Re: So in an event-driven server, how do you ...</A></strong>, S001GMU <a href="mailto:S001GMU#nova,wright.edu">S001GMU#nova,wright.edu</a>, Tue 08 Apr 1997, 02:10 GMT </LI> <LI><strong><A NAME="00040" HREF="msg00040.html">Re: So in an event-driven server, how do you ...</A></strong>, Nathan Yospe <a href="mailto:yospe#hawaii,edu">yospe#hawaii,edu</a>, Tue 08 Apr 1997, 03:42 GMT </LI> <LI><strong><A NAME="00046" HREF="msg00046.html">Re: So in an event-driven server, how do you ...</A></strong>, Chris Gray <a href="mailto:cg#ami-cg,GraySage.Edmonton.AB.CA">cg#ami-cg,GraySage.Edmonton.AB.CA</a>, Tue 08 Apr 1997, 13:08 GMT </LI> <LI><strong><A NAME="00090" HREF="msg00090.html">Re: So in an event-driven server, how do you ...</A></strong>, clawrenc <a href="mailto:clawrenc#xsvr1,cup.hp.com">clawrenc#xsvr1,cup.hp.com</a>, Sat 12 Apr 1997, 04:31 GMT </LI> <LI><strong><A NAME="00088" HREF="msg00088.html">Re: So in an event-driven server, how do you ...</A></strong>, clawrenc <a href="mailto:clawrenc#cup,hp.com">clawrenc#cup,hp.com</a>, Sat 12 Apr 1997, 04:38 GMT </LI> </UL> </LI> <LI><strong><A NAME="00023" HREF="msg00023.html">Re: Resets and repops</A></strong>, coder <a href="mailto:coder#ibm,net">coder#ibm,net</a>, Sun 06 Apr 1997, 04:08 GMT <UL> <li><Possible follow-up(s)><br> <LI><strong><A NAME="00052" HREF="msg00052.html">Re: Resets and repops</A></strong>, S001GMU <a href="mailto:S001GMU#nova,wright.edu">S001GMU#nova,wright.edu</a>, Wed 09 Apr 1997, 05:08 GMT </LI> </UL> </LI> </UL></BLOCKQUOTE> </ul> <hr> <center> [ <a href="../">Other Periods</a> | <a href="../../">Other mailing lists</a> | <a href="/search.php3">Search</a> ] </center> <hr> </body> </html>