Я создаю сервер python, который должен обрабатывать соединение с удаленными узлами на порту 9090 и соединение только с localhost (данные отправки графического интерфейса) на порт 9091. Я думаю, что проблема в том, что в socket.listen (backlog), потому что это блокирует все. Итак, есть способ запустить socket1.listen (backlog) и socket2.listen (backlog) в одно и то же время? Кроме того, является ли хорошей идеей и, прежде всего, безопасным создание сокета для приема данных из графического интерфейса (написанного на Java)?Python, прослушивание на двух сокетах одновременно
ответ
Это может быть сделано в C: Listen to multiple ports from one server
и C++: Create multiple listening sockets
так что вы должны быть в состоянии сделать это в Python.
Единственное, что сделало бы это небезопасным, - это то, что ваш сервер выполняет опасную деятельность в ответ на графический интерфейс, но вы, вероятно, можете добавить код для проверки и защиты от хаков.
Есть вероятность, что кто-то подделает свой IP-адрес в 127.0.0.1 и отправит данные на сервер Python, претендуя на роль графического интерфейса? –
Нет, это специальный адрес «loopback», который работает только на одном компьютере. –
Я использую python2.7.3
, и, как указано в моем комментарии, я не смог воспроизвести проблему блокировки listen
. Примечание:
- ради простоты я только с помощью
IPv4
розетки - Я включил
Python
«s суфлера в коде, чтобы показать, что он не блокировал - относительно возможных проблем безопасности: сокет (
s_local
) прослушивает 9091, принимает соединения только с локального хоста (от других хостов и не будет работать)
Вот отрывок из в CentOS5 Машина:
>>> import socket
>>> s_global = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s_global.bind(("", 9090))
>>> backlog = 0xFF
>>> s_global.listen(backlog)
>>> s_local = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s_local.bind(("127.0.0.1", 9091))
>>> s_local.listen(backlog)
>>>
и вот некоторые выходы на ту же машину:
netstat -an | grep 909
tcp 0 0 0.0.0.0:9090 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9091 0.0.0.0:* LISTEN
Как видно, как сервер сокетов прослушивания подключений.
Теперь, если что-то не так в моих условиях (некоторые чтения показали, что по умолчанию сокеты являются блокировка по умолчанию), после создания каждого сокета, можно добавить (как указано в одном из комментариев) следующую строку (ы):
для s_global
s_global.setblocking(0)
для s_local
s_local.setblocking(0)
Теперь для того, чтобы принимать входящие соединения с обоих сокетов, вы должны использовать Python
«s select module (используется для асинхронной IO) без необходимости для других потоков; приложение-сервер должен постоянно прослушивать соединения, что-то вроде:
TIMEOUT = 1 #seconds
terminate = False # variable to be modified externally to end the loop
listening_sockets = [s_global, s_local]
while (not terminate):
notified_socket_list = select.select(listening_sockets, [], [], TIMEOUT)[0]
for notified_socket in notified_socket_list:
incoming_socket, addr = notified_socket.accept()
handle(incoming_socket, addr)
Примечание: стоит упоминания: Epoll (select.epoll
) является производительность мудрый предпочтительнее выбрать (select.select
), но я не пробовал все же.
Теперь, касательно функции обработки соединений (handle): если ваш сервер разработан только для образовательных целей, вы можете оставить его как есть, но если ваш сервер предназначен для приема большого количества одновременных подключений и большого количества обмен данными с/каждому клиенту, вы должны обрабатывать каждое соединение в отдельной строке (это общий совет, который не применяется к Python
из-за его GIL, иногда потоки только замедляют работу)/процесс как выполненный в SocketServer.py - part of Python's standard library.
@ Edit1 - ответ на 1-й комментарий:
Это просто, все, что вам нужно сделать, это изменить немного в внутреннийfor
петля:
for notified_socket in notified_socket_list:
incoming_socket, addr = notified_socket.accept()
if notified_socket == s_global:
handle_global(incoming_socket, addr)
else:
handle_local(incoming_socket, addr)
или вы можете использовать свое оригинальное решение и выполните различие в соединениях в ручке: аргумент addr
содержит (локальный) порт, к которому подключен сокет; вы можете проверить его и в зависимости от его значения (9090 или 9091) обрабатывать соединение по-разному.
- 1. Прослушивание двух портов одновременно на Java-сервере с использованием многопоточности
- 2. Python - прослушивание двух портов по одному сценарию?
- 3. Выполнение двух функций одновременно на Python
- 4. Прослушивание новых файлов Python
- 5. Блоки feof на сокетах
- 6. Двоичная сериализация на сокетах
- 7. Прослушивание нескольких групп одновременно в SignalR
- 8. Прослушивание нескольких событий нажатия клавиш одновременно
- 9. «Прослушивание» файла в Python
- 10. отправить и получить файл в сокетах python
- 11. Пинг-пакеты на сырых сокетах
- 12. Выполнение двух программ одновременно
- 13. Проверка двух полей одновременно
- 14. Отображение одновременно двух видов
- 15. Как получить доменное имя в сокетах Python?
- 16. Прокрутка двух UITableViews одновременно
- 17. Выбор двух условий одновременно
- 18. Изменение двух списков одновременно
- 19. Вызов двух функций одновременно
- 20. Инициализация двух переменных одновременно
- 21. Запись двух объектов одновременно
- 22. Выполнение двух приложений одновременно
- 23. Выполнение двух потоков одновременно
- 24. Перебор двух переменных одновременно
- 25. Выполнение двух функций одновременно
- 26. Запуск двух таймеров одновременно
- 27. Начало двух мероприятий одновременно
- 28. Выполнение двух функций одновременно
- 29. Отображение двух фрагментов одновременно
- 30. Воспроизведение двух аудиопотоков одновременно
Почему бы не использовать нить? первый сокет не будет блокировать другой сокет. –
Ваш вопрос несколько расплывчатый, но да, возможно, вам нужна другая нить, предпочтительно нить для каждого сокета. Попробуйте обернуть функциональность сокета в новом классе, наследуйте этот класс от Thread, а затем просто создайте новый экземпляр класса для каждого порта. – Dan
Используете ли вы существующий веб-сервер python или пишете свой собственный? Я бы не использовал сокет для получения данных gui лично. Я думаю, что вы ищете «межпроцессные коммуникации», такие как D-Bus, XML-RPC и другие. – NuclearPeon