Простой демон службы Windows 10, который слушает на TCP-порту?

Вопрос или проблема

Для тестирования мне нужен очень простой сервер, который может функционировать как полноценная служба Windows 10 и слушать на TCP-порту.

Я сначала подумал запустить python3 -m http.server 8000 – но это работает в “фоновом” режиме и определенно не является службой Windows.

Потом я нашел https://gist.github.com/jorgepsmatos/9aa0fef750baccf6d6abe457b911afef – это, похоже, обертка службы Windows вокруг веб-сервера.

Проблема в том, что веб-сервер – это SimpleHTTPServer, который написан на Python2 (Python3 – это http.server), и остальной код, похоже, тоже написан для Python2.

В любом случае, после некоторых доработок я добился следующего:

C:\tmp\win_serv_py_http_git>python.exe Server.py install
Установка службы PythonHttpServer
копирование исполняемого файла ...
копирование вспомогательной dll ...
Служба установлена

C:\tmp\win_serv_py_http_git>D:\msys64\mingw64\bin\python.exe Server.py start
Запуск службы PythonHttpServer
Ошибка при запуске службы: Служба не ответила на запрос на запуск или управление в установленный срок.

Так что я не могу запустить это – и не уверен, стоит ли вообще пытаться заставить это работать, поскольку в конце концов мне это нужно как “пустышка” в более крупном тесте.

С учетом сказанного, есть ли какая-то “базовая демо” служба Windows, которая слушает на TCP-порту – предпочтительно доступная для загрузки в виде уже собранного исполняемого файла (так как язык не имеет значения; пока он является тривиально простым, и я устанавливаю порт, на котором она слушает) – которую я мог бы “установить”, “запустить”/”остановить” или “удалить” как службу Windows?

Я только что потратил некоторое время на создание этого для вас… должно работать нормально, так как я только что проверил это на Windows 11… должно работать и на 10. Интересный маленький проект, так как я никогда не завершал это ранее.

Убедитесь, что вы скачали Python – последняя версия на данный момент v3.11.5

Сервер на Python: (сохраните это как testserver.py или любое другое имя.)

import socket

def start_tcp_listener():
    host="0.0.0.0"  # Слушать на всех доступных сетевых интерфейсах
    port = 8080

    listener_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    listener_socket.bind((host, port))
    listener_socket.listen(5)

    print(f"Слушаем входящие соединения на {host}:{port}")

    while True:
        client_socket, addr = listener_socket.accept()
        print(f"Клиент подключен с {addr[0]}:{addr[1]}")

        # Отправить приветственное сообщение клиенту
        client_socket.send(b"Добро пожаловать на сервер!")

        while True:
            try:
                # Получить данные от клиента
                data = client_socket.recv(1024)
                if not data:
                    break  # Нет больше данных, закрыть соединение

                print(f"Получено от клиента: {data.decode()}")

                # Отправить ответ клиенту
                client_socket.send(b"Сервер получил ваше сообщение!")
            except ConnectionResetError:
                break  # Соединение закрыто клиентом

        # Закрыть сокет клиента по завершении
        client_socket.close()

if __name__ == "__main__":
    start_tcp_listener()

Клиент на Python: (сохраните это как testclient.py или любое другое имя.)

import socket

def connect_to_server():
    host="127.0.0.1"  # Замените на фактический IP-адрес вашего сервера
    port = 8080  # Убедитесь, что он соответствует порту, на котором слушает ваш сервер

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

    try:
        client_socket.connect((host, port))
        print(f"Подключено к серверу по {host}:{port}")
    except ConnectionRefusedError:
        print("Подключение отклонено. Убедитесь, что сервер работает.")
        return

    # Отправить данные на сервер, если это необходимо
    client_socket.send(b"Привет, сервер!")

    # Получить данные от сервера, если это необходимо
    data = client_socket.recv(1024)
    print("Получено от сервера:", data.decode())

    client_socket.close()

if __name__ == "__main__":
    connect_to_server()

Затем откройте / сохраните этот код в VSCode или в вашей предпочитаемой IDE.

Рабочие примеры:
Сервер
Клиент

Сейчас соединение закрывается после успешного теста, но вы можете легко изменить это, закомментировав client_socket.close() на строке 35 в testserver.py и client_socket.close() на строке 23 в testclient.py, добавив # перед каждой соответствующей строкой.

Ответ или решение

Создание простого TCP-сервера в качестве службы Windows на Python – это отличный способ освоить работу с сетевыми сокетами и службами Windows. Ниже приведены подробные шаги по созданию такой службы, которая будет прослушивать TCP-порт.

Установка Python

Сначала убедитесь, что у вас установлен Python. Вы можете скачать последнюю версию здесь. Например, на момент написания последняя версия – 3.11.5.

Создание TCP-сервера

  1. Создайте файл с именем TcpService.py и добавьте в него следующий код:
import socket
import sys
import os
import servicemanager
import win32serviceutil
import win32service
import win32event

class TcpService(win32serviceutil.ServiceFramework):
    _svc_name_ = 'TcpListeningService'
    _svc_display_name_ = 'TCP Listening Service'
    _svc_description_ = 'Служба, которая прослушивает входящие TCP-трафики'

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.stop_event = win32event.CreateEvent(None, 0, 0, None)
        self.running = True
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind(('0.0.0.0', 8080))  # Измените порт при необходимости
        self.server_socket.listen(5)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.stop_event)
        self.running = False
        self.server_socket.close()

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

    def main(self):
        while self.running:
            try:
                client_socket, addr = self.server_socket.accept()
                servicemanager.LogInfoMsg(f'Клиент подключен: {addr}')
                client_socket.send(b'Добро пожаловать на сервер!\n')

                while True:
                    data = client_socket.recv(1024)
                    if not data:
                        break
                    servicemanager.LogInfoMsg(f'Получено от клиента: {data.decode()}')
                    client_socket.send(b'Сервер получил ваше сообщение!\n')

                client_socket.close()
            except Exception as e:
                servicemanager.LogErrorMsg(f'Ошибка: {str(e)}')

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(TcpService)

Установка необходимых библиотек

Для запуска этой службы вам понадобятся модули pywin32. Вы можете установить их с помощью pip:

pip install pywin32

Установка и запуск службы

  1. Откройте командную строку с правами администратора.
  2. Перейдите в каталог, где находится ваш найденный файл TcpService.py.
  3. Выполните установку службы:
python TcpService.py install
  1. При необходимости запустите службу:
python TcpService.py start
  1. Чтобы остановить или удалить службу, используйте следующие команды:
python TcpService.py stop
python TcpService.py remove

Примечания

  • Убедитесь, что порт, на котором прослушивает служба, не занят другими приложениями или службами.
  • Вы можете изменять логику обработки клиентов в методе main. Например, можно добавить больше функционала по обработке сообщений.

Этот пример должен работать на Windows 10 и выше. Если у вас возникнут какие-либо проблемы или вопросы, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...