TCP server as a Windows service using Python?

D

David Mitchell

Hello group,

I'm trying to create a TCP server using Python, and I want it to run under
Windows as a service.

Now, I'm fine with building the TCP server using Python - done it lots of
times, and I know there's lots of sample code out there I can grab if I
ever need to.

Equally, I think I've got the simpler concepts about creating Windows
services using Python clear. I've got the Python Win32 book, worked
through the example code in there and haven't had any real problems with
it.

Where I'm having trouble is with the overlapped I/O call. When I create a
TCP server, I need to have it sit there waiting for a client
connection. With a Windows service, it has to sit there waiting for
administrative messages such as e.g. a "stop service" message. The
example code in the Python Win32 book uses named pipes to do IO -
I'm constrained to using TCP sockets.

I can't see how to let the service accept *either* an incoming TCP client
connection *or* an e.g. "stop service" message. If someone could point me
to some sample code, I'd greatly appreciate it - Google hasn't been
helpful.

Thanks in advance

Dave M.
 
D

David Bolen

David Mitchell said:
I can't see how to let the service accept *either* an incoming TCP client
connection *or* an e.g. "stop service" message. If someone could point me
to some sample code, I'd greatly appreciate it - Google hasn't been
helpful.

NT Services generally run a dedicated thread to handle service control
messages - normally the application starts up and lets its main thread
handle that, and it starts a secondary thread to actually run the
application code.

It's been a while since I last used it, but if you are using the
service support from win32all then I believe it should handle it
automatically for you. If you subclass from
win32serviceutil.ServiceFramework, then the Svc* control message calls
(such as SvcStop) should, I believe, arriving in a different thread
from your main execution. (*)

Thus, your client side processing only has to wait for the TCP
connection. The stop service connection is handled in the service
message thread, which the framework will turn into the method call.

Now, you do have to figure out how you want to interrupt your TCP
client processing when you get such a stop message. The demo with
win32all uses an event which it can wait on along with the pipes. You
could do the same thing with sockets if you used native Windows
operations, but if you're using more portable Python stuff, I'd
probably just have a periodic timeout to your select to check a flag,
or even have an internal loopback socket that you write to to wake up
the select and then it can shut down.

-- David

(*) If for some reason this isn't the case, you can still architect
your service this way - just spin off a new thread at startup to
handle your TCP clients.
 
S

Shalabh Chaturvedi

David Mitchell said:
Hello group,

I'm trying to create a TCP server using Python, and I want it to run under
Windows as a service. ....
I can't see how to let the service accept *either* an incoming TCP client
connection *or* an e.g. "stop service" message. If someone could point me
to some sample code, I'd greatly appreciate it - Google hasn't been
helpful.

An alternative solution might be to split the functionality into two
processes. The Windows service launches a second (TCP server) process,
which it later kills upon being asked to stop.
 
J

John Abel

I don't know if this will be of use to you. Here's a snip of code, that
I used to run a web server as a service. It uses my custom module based
on SimpleHTTPServer, but you get the idea.

HTH

J

def SvcDoRun( self ):
threadEvent = threading.Event()
threadEvent.set()
webUI = httpWebService( threadEvent )
webUI.start()

win32event.WaitForSingleObject( self.hWaitStop,
win32event.INFINITE )

threadEvent.clear()
webUI.join()

class httpWebService( threading.Thread ):

def __init__( self, eventNotifyObj ):
threading.Thread.__init__( self )
self.notifyEvent = eventNotifyObj

def run ( self ):
serverPort = 10080
SimpleHTTPServer2.SimpleHTTPRequestHandler.documentRoot =
"F:\Temp\HTTPR
oot"
httpServer = SimpleHTTPServer2.HTTPServer( ('', serverPort),
SimpleHTTPS
erver2.SimpleHTTPRequestHandler )
httpServerWait = httpServer.fileno()
while self.notifyEvent.isSet():
httpReady = select.select( [httpServerWait], [], [], 1)
if httpServerWait in httpReady[0]:
httpServer.handle_request()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top