gpt4 book ai didi

作为 Windows 服务的 Python XML-RPC 服务器

转载 作者:太空狗 更新时间:2023-10-29 21:44:21 27 4
gpt4 key购买 nike

我正在尝试创建一个 XML-RPC 服务器作为 Windows 服务。
XML-RPC 服务器能够获取和放置文件(如 FTP)和
还通过远程客户端的 os.system() 执行命令
发送给它。

我正在尝试将服务器封装在 windows 服务中
事件循环。

创建服务时没有问题。

python.exe remoteServer.py --startup=auto install
Installing service XMLRPCServerService
Service installed

启动服务时没有问题。

python.exe remoteServer.py start
Starting service XMLRPCServerService

停止服务时没有问题。

python.exe remoteServer.py stop
Stopping service XMLRPCServerService

再次启动服务时出现问题。

python.exe remoteServer.py start
Starting service XMLRPCServerService
Error starting service: An instance of the service is already running.

查看进程监视器,我看到一个进程“pythonservice.exe”是
仍在运行。

remoteServer.py 的内容如下:

#!/bin/python

# $Revision: 1.7 $
# $Author: dot $
# $Date: 2011/12/07 01:16:13 $

LISTEN_HOST='0.0.0.0'
LISTEN_PORT=8000

import os
import SocketServer
import BaseHTTPServer
import SimpleHTTPServer
import xmlrpclib
import SimpleXMLRPCServer
import socket
import httplib
import inspect
import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil

class XMLRPCServer(BaseHTTPServer.HTTPServer,SimpleXMLRPCServer.SimpleXMLRPCDispatcher):
def __init__(self, server_address, HandlerClass, logRequests=True):
""" XML-RPC server. """
self.logRequests = logRequests

SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self,False,None)
SocketServer.BaseServer.__init__(self, server_address, HandlerClass)

self.socket = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)

self.server_bind()
self.server_activate()

class XMLRPCRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
""" XML-RPC request handler class. """
def setup(self):
self.connection = self.request
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)

def do_POST(self):
""" Handles the HTTPS request.
It was copied out from SimpleXMLRPCServer.py and modified to shutdown the socket cleanly.
"""

try:
# get arguments
data = self.rfile.read(int(self.headers["content-length"]))
# In previous versions of SimpleXMLRPCServer, _dispatch
# could be overridden in this class, instead of in
# SimpleXMLRPCDispatcher. To maintain backwards compatibility,
# check to see if a subclass implements _dispatch and dispatch
# using that method if present.
response = self.server._marshaled_dispatch(
data, getattr(self, '_dispatch', None)
)
except:
# This should only happen if the module is buggy
# internal error, report as HTTP server error
self.send_response(500)
self.end_headers()
else:
# got a valid XML RPC response
self.send_response(200)
self.send_header("Content-type", "text/xml")
self.send_header("Content-length", str(len(response)))
self.end_headers()
self.wfile.write(response)

# shut down the connection
self.wfile.flush()
self.connection.shutdown() # Modified here!

def XMLRPCServerGet(HandlerClass = XMLRPCRequestHandler,ServerClass = XMLRPCServer):
"""Test xml rpc over http server"""
class xmlrpc_registers:
def _listMethods(self):
return list_public_methods(self)

def _methodHelp(self, method):
f = getattr(self, method)
return inspect.getdoc(f)

def list(self, dir_name):
"""list(dir_name) => [<filenames>]

Returns a list containing the contents of the named directory.
"""
return os.listdir(dir_name)

def put(self,filename,filedata):
try:
with open(filename, "wb") as handle:
handle.write(filedata.data)
handle.close()
return True
except Exception,ex:
return 'error'

def get(self,filepath):
try:
handle = open(filepath)
return xmlrpclib.Binary(handle.read())
handle.close()
except:
return 'error'

def system(self, command):
result = os.system(command)
return result

server_address = (LISTEN_HOST, LISTEN_PORT) # (address, port)
server = ServerClass(server_address, HandlerClass)
server.register_introspection_functions()
server.register_instance(xmlrpc_registers())
#sa = server.socket.getsockname()
return server
#server.serve_forever()
#print "Serving HTTP on", sa[0], "port", sa[1]
#try:
# #print 'Use Control-C to exit'
# server.serve_forever()
#except KeyboardInterrupt:
# #print 'Exiting'

class XMLRPCServerService(win32serviceutil.ServiceFramework):
_svc_name_ = "XMLRPCServerService"
_svc_display_name_ = "XMLRPCServerService"
_svc_description_ = "Tests Python service framework by receiving and echoing messages over a named pipe"

def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)

def SvcDoRun(self):
import servicemanager
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))
self.timeout = 100
server = XMLRPCServerGet()
#server.serve_forever()

while 1:
# Wait for service stop signal, if I timeout, loop again
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
# Check to see if self.hWaitStop happened
if rc == win32event.WAIT_OBJECT_0:
# Stop signal encountered
server.shutdown()
servicemanager.LogInfoMsg("XMLRPCServerService - STOPPED")
break
else:
server.handle_request()
servicemanager.LogInfoMsg("XMLRPCServerService - is alive and well")

def ctrlHandler(ctrlType):
return True

if __name__ == '__main__':
win32api.SetConsoleCtrlHandler(ctrlHandler, True)
win32serviceutil.HandleCommandLine(XMLRPCServerService)

最佳答案

看起来您在 SvcStop 方法末尾缺少对 self.ReportServiceStatus(win32service.SERVICE_STOPPED) 的调用。

关于作为 Windows 服务的 Python XML-RPC 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8409608/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com