Создание сокета только для локальных соединений - PullRequest
8 голосов
/ 26 января 2010

У меня есть программа на Python со многими потоками. Я думал о создании сокета, связал его с localhost, и чтобы потоки читали / записывали в это центральное место. Однако я не хочу, чтобы этот сокет был открыт для остальной части сети, следует принимать только соединения от 127.0.0.1. Как бы я это сделал (в Python)? И это подходящий дизайн? Или есть что-то более элегантное?

Ответы [ 6 ]

6 голосов
/ 26 января 2010

Учитывая сокет, созданный с помощью socket.socket(), вы можете использовать bind() перед прослушиванием:

socket.bind(('127.0.0.1', 80))

Использование адреса 127.0.0.1 указывает, что сокет должен связываться только с локальным интерфейсом.

5 голосов
/ 26 января 2010

http://www.amk.ca/python/howto/sockets/

Показывает пример сокета. Этот лакомый кусочек тебе интересен я думаю

мы использовали socket.gethostname (), чтобы сокет был виден внешнему миру. Если бы мы использовали s.bind (('', 80)) или s.bind (('localhost', 80)) или s.bind (('127.0.0.1', 80)), у нас все равно был бы "сервер "сокет, но тот, который был виден только внутри той же машины.

Я думаю, что ваш ответ ( см. Ниже для исправления )

Что касается правильности использования этого метода для связи потоков. Я не уверен, насколько хорошо это обрабатывает несколько потоков и чтение / запись

EDIT

Похоже, что приведенный ниже рецепт Python связывает некоторые потоки

http://code.activestate.com/recipes/491281/

Веселись!

EDIT

Статья неверна и, как указано, " s.bind (('', 80)) будет связываться с INADDR_ANY "

3 голосов
/ 26 января 2010

Если вы работаете в системе на основе UNIX, вы можете рассмотреть возможность использования доменных сокетов UNIX вместо интернет-сокетов. Я думаю, что-то вроде следующего должно работать:

>>> # in one window/shell
>>> import socket
>>> sd = socket.socket(socket.AF_UNIX)
>>> sd.bind('/path/to/my/socket')
>>> sd.listen(5)
>>> (client,addr) = sd.accept()
>>> client.recv(1024)
'hello'
>>>

>>> # in a different shell
>>> import socket
>>> sd = socket.socket(socket.AF_UNIX)
>>> sd.connect('/path/to/my/socket')
>>> sd.send('hello')
2 голосов
/ 26 января 2010

Возможно, вы захотите использовать вместо этого модуль очереди из стандартной библиотеки. Он разработан специально для облегчения связи между потоками. Цитата из документов:

Модуль Queue реализует многопользовательские, многопользовательские очереди. Это особенно полезно в многопоточном программировании, когда необходимо безопасно обмениваться информацией между несколькими потоками. Класс Queue в этом модуле реализует всю необходимую семантику блокировки. Это зависит от наличия поддержки потоков в Python; см. резьбовой модуль.

0 голосов
/ 26 января 2010

ПримечаниеВ сетях TCP / IP 127.0.0.0/8 - это сеть без маршрутизации, поэтому вы не должны иметь возможность отправлять дейтаграмму IP, предназначенную для 127.0.0.1, через маршрутизируемую инфраструктуру. Маршрутизатор просто отбросит датаграмму. Тем не менее, можно создавать и отправлять дейтаграммы с адресом назначения 127.0.0.1, поэтому хост в той же сети (по IP-адресу сети), что и ваш хост, может получить дейтаграмму в стек TCP / IP вашего хоста. Это где ваш местный firewal вступает в игру. Ваш локальный (хост) брандмауэр должен иметь правило, которое отбрасывает дейтаграммы IP, предназначенные для 127.0.0.0/8, поступающие в любой интерфейс, кроме lo0 (или эквивалентный интерфейс обратной связи). Если ваш хост 1) имеет такие правила брандмауэра или 2) существует в своей собственной сети (или используется только с полностью доверенными хостами) и за хорошо настроенным маршрутизатором, вы можете просто подключиться к 127.0.0.1 и быть уверенным, что любой датаграммы, которые вы получаете на сокете, пришли с локальной машины. Предыдущие ответы касаются того, как открыть и привязать к 127.0.0.1.

0 голосов
/ 26 января 2010

Если вы выполните sock.bind ((port, '127.0.0.1')), он будет прослушивать только локальный хост, а не другие интерфейсы, так что это все, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...