Не удается получить правильный IP-адрес однорангового узла при приеме подключения через сокет TCP на локальном хосте в Python - PullRequest
0 голосов
/ 30 мая 2020

Я работаю над кодом сетевого приложения P2P для передачи файлов. У каждого однорангового узла есть прослушивающий сокет, на котором он может принимать входящие соединения.

«Серверная» часть кода:

listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listening_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

try:
    listening_socket.bind((self.address, self.listening_port))
    break
except SocketError:
    return

listening_socket.listen(5)
listening_socket.setblocking(0)
self.listening_socket = listening_socket

####

new_connection, address = self.listening_socket.accept()
new_connection.setblocking(0)
print 'Accepted new connection from %s' % (peer_address)

«Клиентская» часть код:

try:
    sock = socket.create_connection((peer_address, peer_port), timeout=5)
except socket.error:
    return False
print 'Connected to %s' % (peer_address)

sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setblocking(0)

Если я привяжу первый одноранговый узел (сервер) к «127.0.0.1», а второй (клиент) к «127.0.0.2» (или любой другой адрес из loopback su bnet) и подключиться к «127.0.0.1», accept () возвращает адрес как «127.0.0.1» вместо «127.0.0.2». Как я могу отобразить правильный входящий IP-адрес при принятии соединения?

getpeername () также возвращает «127.0.0.1».

В локальной сети Wi-Fi отображается правильный входящий IP-адрес. Я упоминаю, что само соединение работает хорошо, мне просто нужно отобразить правильный адрес, а не «127.0.0.1».

Тестирование на Unix машине.

Буду признателен за любую помощь .

1 Ответ

0 голосов
/ 30 мая 2020

Если TCP-клиент явно не привязан к локальному IP-адресу, он может использовать любой из локальных IP-адресов на интерфейсе, который обеспечивает маршрут к целевому IP. Обычно системы имеют неявный внутренний порядок, и первый IP-адрес используется, если доступно несколько.

В вашем случае вы подключаетесь только к целевому IP 127.0.0.2. Этот IP-адрес доступен как из 127.0.0.1, так и из 127.0.0.2 с одинаковой стоимостью. 127.0.0.1, вероятно, является первым IP-адресом на интерфейсе обратной связи, поэтому он используется в качестве исходного IP-адреса. Если вы хотите, чтобы он был другим, вам необходимо явно привязать соединительный сокет. Не имеет значения, что происходит на вашем прослушивающем сокете - привязка осуществляется для каждого сокета, а не для приложения.

Привязка клиентского сокета аналогична привязке серверного сокета:

s = socket.socket()
s.bind(('127.0.0.2',0))
s.connect(('127.0.0.2', peer_port))
...