[Go to Google Groups Home] Advanced Groups Search Groups Help Groups Viewing message <01I9FF7ZR2J2QO5Z7K@TGV.COM> From: Aaron Leonard (AARON@TGV.COM) Subject: Re: Examples of multi-threaded standalone server Newsgroups: vmsnet.networks.tcp-ip.multinet Date: 1996/09/13 View: Complete Thread (3 articles) | Original Format > I've written a server for Multinet is executed for each connection > by the Multinet "master" listener. > It works great except that the UIC is improper and causing all sorts > of problems. > How do I write my own standalone server that is also MULTITHREADED. > The examples in MULTINET_ROOT:[examples] are fine, but the listener > blocks while processing a request. First - it doesn't sound like you're asking for an actual "multithreaded" server process - I take the term "multithreaded" to refer to a single process that handles multiple connections "concurrently". What you're asking for is a server process that creates a separate worker process to service each connection. (For the record, there are various ways of writing a multithreaded server process - ASTs, select(), DECthreads ...) > I need the listener to "peel" off a connection, spawn a separate process > to handle it, and go back to listening. > Here is the algorithm > while (true) { > 1. Listen for a new connection > 2. "Peel" off the new connection > 3. Create a separate process to handle this connection, > handing off the channel to the new process. > } > Anybody got an example of how to create the separate process and > hand it the channel? OK - your starting point (assuming that you're doing TCP) would be TCPECHOSERVER-STANDALONE.C. You need the following logic from this (as I infer you've already figured out.) main() { s = socket(); /* create the listen socket */ /* always set SO_REUSEADDR on a server socket */ setsockopt(s,SOL_socket,SO_REUSEADDR...); bind(); /* bind() to local addr INADDR_ANY & the desired local port */ /* listen to incoming connections - specify really large BACKLOG * to deal with weird Internet (SOMAXCONN needs boosted to * increase effective BACKLOG past 5 [which means 8]) */ listen(s, 50); while (1) { vs = accept(s, ...); /* got a live connection - accept it */ /* here we set the socket to be handoffable, and $CREPRC * the worker process to grab this socket and deal with it */ } } The missing piece is: once the parent server has grabbed the live connection, how do we create the desired worker process, and how do we hand off the socket to that process? Example code can be found in ftp://public.tgv.cisco.com/aaron/handoff/ . First you do an INET_HANDOFF $QIOW IO$_SETCHAR: #define INET_HANDOFF 4 SetChar_Mode = INET_HANDOFF; Status = sys$qiow(0, s, IO$_SETCHAR,iosb,0,0, &SetChar_Mode,0,0,0,0,0); Then you $DASSGN the channel, then you $CREPRC the child. The child just does an $ASSIGN to the channel and away it goes. This is pretty much shown in ftp://public.tgv.cisco.com/aaron/handoff/handoff.c. The one missing part for your standalone server is the code where the parent figures out the INETnnn: device name corresponding to the channel. This can be done with a $GETDVI against the channel. Hope this is clear enough - I probably should put together a complete example one of these days. Cheers, Aaron Aaron Leonard aaron@cisco.com / aaron@tgv.com cisco MultiNet for OpenVMS Support --------------------------------------------------------------------------- Google Home - Advertise with Us - Search Solutions - News and Resources - Language Tools - Jobs, Press, Cool Stuff... ©2002 Google