2016-06-06 65 views
0

我有一個簡單的Syslog接收器,作爲Windows服務啓動。該服務啓動得很好......但是當我點擊「停止服務」時,我無法停下來。我確定這是因爲我綁定了一個套接字。但是,我無法弄清楚如何從SvcStop函數中解除綁定到套接字。有人有主意嗎?Python,停止Windows服務(從套接字解除綁定)

OUTPUT_LOG_FILE = 'C:\temp\output.log' 
HOST = "192.168.X.X" 
PORT = 514 
import SocketServer 
import pythoncom 
import win32serviceutil 
import win32service 
import win32event 
import servicemanager 
import socket 

class AppServerSvc (win32serviceutil.ServiceFramework): 
    _svc_name_ = "Simple Syslog Receiver" 
    _svc_display_name_ = "Simple Syslog Receiver" 
    server = "" 

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

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

    def SvcDoRun(self): 
     servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, 
           servicemanager.PYS_SERVICE_STARTED, 
           (self._svc_name_,'')) 
     self.main() 

    def main(self): 
     try: 
      global server 
      server = SocketServer.UDPServer((HOST, PORT), SyslogUDPHandler) 
      server.serve_forever(poll_interval=0.5) 
     except (IOError, SystemExit): 
      raise 
     pass 



class SyslogUDPHandler(SocketServer.BaseRequestHandler): 

    def handle(self): 
     data = bytes.decode(self.request[0].strip()) 

     with open(OUTPUT_LOG_FILE, 'w+') as outputfile: 
      outputfile.write(str(data)) 
     outputfile.close() 

if __name__ == "__main__": 
    win32serviceutil.HandleCommandLine(AppServerSvc) 
+0

當你停止服務,你必須調用服務器上的['shutdown'(https://docs.python.org/2/library/socketserver.html#SocketServer.BaseServer.shutdown)方法。 – eryksun

回答

0

在Windows 7 + VirtualBox上出現同樣的問題。

我唯一的解決方案是刪除這個特定的端口在VirtualBox中轉發或使用新的端口。

即使從基本的例子標準socket服務器代碼具有這樣的特徵:1。 它運行永遠 2.你不能看到它的Windows進程 3.它不是「因爲它爲界將套接字」作爲儘管Python應用程序已關閉,它仍會繼續正常重播。

import socket 

    TCP_IP = '127.0.0.1' 
    TCP_PORT = 80 
    BUFFER_SIZE = 20 

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.bind((TCP_IP, TCP_PORT)) 
    s.listen(1) 

    conn, addr = s.accept() 
    print 'Connection address:', addr 
    while 1: 
     data = conn.recv(BUFFER_SIZE) 
     if not data: break 
     print "received data:", data 
     conn.send(data) # echo 

    conn.close() 
    s.close() 
    raw_input()