Вопрос или проблема
Для тестирования мне нужен очень простой сервер, который может функционировать как полноценная служба 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-сервера
- Создайте файл с именем
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
Установка и запуск службы
- Откройте командную строку с правами администратора.
- Перейдите в каталог, где находится ваш найденный файл
TcpService.py
. - Выполните установку службы:
python TcpService.py install
- При необходимости запустите службу:
python TcpService.py start
- Чтобы остановить или удалить службу, используйте следующие команды:
python TcpService.py stop
python TcpService.py remove
Примечания
- Убедитесь, что порт, на котором прослушивает служба, не занят другими приложениями или службами.
- Вы можете изменять логику обработки клиентов в методе
main
. Например, можно добавить больше функционала по обработке сообщений.
Этот пример должен работать на Windows 10 и выше. Если у вас возникнут какие-либо проблемы или вопросы, не стесняйтесь обращаться за помощью!