Код самого сервиса есть. a123.py
debug = False
import asyncore
import socket
import random
import CRC16
import Int_Str
def make_packet_ans(Command, derection, data = None):
u'''подготавливаем пакет для посылки'''
#собираем пакет в сообтветствии с ыорматом
packet = Command + derection
if data:
#обрезаем ответ до двух байт
if data > 1<<16:
data = data % 1<<16
packet = packet + chr(data/256) + chr(data%256)
else:
packet = packet + '\x00\x00'
#вычисляем CRC
crc = CRC16.generate_crc(packet)
crc_str = Int_Str.int2str(command=crc, message_length=2)
#добавляем CRC
packet += crc_str
if debug:
Int_Str.print_command(packet)
#возвращаем пакет
return packet
def check_packet(packet):
u'''проверяем принятый пакет CRC16'''
#вычисляем CRC для информациионной части
crc = CRC16.generate_crc(packet[:-2])
crc_str = Int_Str.int2str(command=crc, message_length=2)
if debug:
Int_Str.print_command(crc),Int_Str.print_command(packet[-2:])
#возвращаем результат
if crc_str == packet[-2:]:
return True
else:
return False
class EchoHandler(asyncore.dispatcher_with_send):
def handle_read(self):
print "readed"
data = self.recv(6)
if len(data) == 6:
if check_packet(data):
INT = random.randint(0,1<<16)
INT_0 = INT / (1<<8)
INT_1 = INT % (1<<8)
#data = data[:2]+chr(INT_0)+chr(INT_1)+data[-2:]
data = make_packet_ans(Command = data[0], derection=data[1], data = INT)
self.send(data)
else:
self.send(data)
self.close()
def handle_expt(self):
self.close() # connection failed, shutdown
class EchoServer(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind((host, port))
self.listen(5)
def handle_accept(self):
pair = self.accept()
if pair is None:
pass
else:
sock, addr = pair
print 'Incoming connection from %s' % repr(addr)
handler = EchoHandler(sock)
if __name__ == "__main__":
server = EchoServer(host = 'localhost', port = 1600)
asyncore.loop(0.1)
import win32serviceutil
import win32service
import win32event
import servicemanager
import a123
import asyncore
class AppServerSvc (win32serviceutil.ServiceFramework):
_svc_name_ = "DummyService"
_svc_display_name_ = "Dummy Service"
_svc_description_ = "Dummy Service Description"
def __init__(self,args):
win32serviceutil.ServiceFramework.__init__(self,args)
self.hWaitStop = win32event.CreateEvent(None,0,0,None)
self.hWaitResume = win32event.CreateEvent(None, 0, 0, None)
self.timeout = 2000 #Пауза между выполнением основного цикла службы в миллисекундах
self.resumeTimeout = 1000
self._paused = False
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING, 1000)
win32event.SetEvent(self.hWaitStop)
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, ''))
def SvcPause(self):
self.ReportServiceStatus(win32service.SERVICE_PAUSE_PENDING)
self._paused = True
self.ReportServiceStatus(win32service.SERVICE_PAUSED)
servicemanager.LogInfoMsg("The %s service has paused." % (self._svc_name_, ))
def SvcContinue(self):
self.ReportServiceStatus(win32service.SERVICE_CONTINUE_PENDING)
win32event.SetEvent(self.hWaitResume)
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
servicemanager.LogInfoMsg("The %s service has resumed." % (self._svc_name_, ))
def SvcDoRun(self):
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_,''))
self.main()
#В этом методе реализовываем нашу службу
def main(self):
#Здесь выполняем необходимые действия при старте службы
servicemanager.LogInfoMsg("Hello! I'm a Dummy Service.")
server = a123.EchoServer(host = 'localhost', port = 1600)
while True:
#Здесь должен находиться основной код сервиса
servicemanager.LogInfoMsg("I'm still here.")
asyncore.loop(0.1)
servicemanager.LogInfoMsg("after loop")
# Проверяем не поступила ли команда завершения работы службы
rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
if rc == win32event.WAIT_OBJECT_0:
# Здесь выполняем необходимые действия при остановке службы
servicemanager.LogInfoMsg("Bye!")
break
# Здесь выполняем необходимые действия при приостановке службы
if self._paused:
servicemanager.LogInfoMsg("I'm paused... Keep waiting...")
# Приостановка работы службы
while self._paused:
# Проверям не поступила ли команда возобновления работы службы
rc = win32event.WaitForSingleObject(self.hWaitResume, self.resumeTimeout)
if rc == win32event.WAIT_OBJECT_0:
self._paused = False
# Здесь выполняем необходимые действия при возобновлении работы службы
servicemanager.LogInfoMsg("Yeah! Let's continue!")
break
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(AppServerSvc)
после этого необходимо зарегестрировать службу - в консоли
python service_test.py install
В связи с этим несколько вопросов:
Как я понимаю asyncore.loop(0.1) не завершается, по крайней мере не в лог строчка после него не попадает, хотя, если запустить отдельным потоком, то по таймауту завершается. В чём может быть причина?
Как узнать, что asyncore.loop уже запущен, а то может быть я просто создаю кучу обработчиков?
Возможно ли принудительно завершить asyncore.loop? На случай, если вдруг захочу остановить сервис не дожидаясь окончания обработки принятых пакетов(они могут идти практически бесконечно).
На 2,3 вопросы в документации ответов не нашёл