Создание сокета с тем же IP и портом на локальном хосте - PullRequest
4 голосов
/ 26 октября 2010

Я наблюдаю странное поведение в Linux, когда вижу, что удаленный конец и локальный конец показывают одинаковую комбинацию IP и порта. Ниже приводится вывод netstat

netstat -anp | grep 6102

tcp 0 0 139.185.44.123:61020 0.0.0.0:* LISTEN 3361 / a.out
tcp 0 0 139.185.44.123:61021 139.185.44.123:61021 УСТАНОВЛЕНО 3361 / a.out

Может кто-нибудь сказать мне, если это вообще возможно? Если да, то какой может быть сценарий?

Ответы [ 5 ]

3 голосов
/ 29 мая 2012

Соединение идентифицируется 4-мя кортежами ((исходный ip, исходный порт), (целевой ip, целевой порт)), и исходный и целевой порты могут быть одинаковыми без каких-либо проблем.Это соединение могло бы даже быть установлено одним процессом, что привело бы к выводу, который вы видите.

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

Проблема повторной попытки заключалась в том, что если приложение сервера не работало И исходный порт, выбранный случайным образом, совпадал с целевым портом (которыйвозможно, потому что целевой порт находился в эфемерном диапазоне), клиентский сокет СОЕДИНЯЕТСЯ С СЕБЕ (который наносит ущерб внутренней логике клиентского приложения, вы можете себе представить).

Поскольку клиент выполнялповторяется как можно быстрее, вероятность того, что это может произойти, составляет 1 к 30 000.

Следующий скрипт Python воспроизводит его:

import socket

host = 'localhost'
port = 35911

ctr = 0
while True:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(5)
        ctr += 1
        s.connect((host, port))
        print "Connected to self after", ctr, "tries"
        break
    except socket.error, e:
        print e
        # Retry
2 голосов
/ 26 октября 2010

Вот воображаемый сценарий.Вызывающая сторона connect может вызвать bind перед вызовом connect.Вызывающий объект connect может взаимодействовать с вызывающим объектом listen и намеренно связываться с номером порта 1, превышающим номер порта прослушивания.

Если ядро ​​продолжит повторное использование номера сокета для слушателя, я бычто ошибка в ядре.

1 голос
/ 08 ноября 2010

Это немного странный случай, называемый TCP "активное / активное открытие".Сокет был открыт, привязан к локальному порту и затем подключен к себе, используя connect() с его собственным адресом в качестве пункта назначения.

1 голос
/ 26 октября 2010

Когда многопоточное серверное программное обеспечение принимает соединение, оно обычно создает другой сокет, который связывается с вновь подключенным клиентом в отдельном потоке, в то время как исходный серверный сокет все еще ожидает новых клиентов в исходном потоке. В таких случаях порты обоих сокетов равны. Так что проблем нет.

0 голосов
/ 27 октября 2010

Ничего странного в этом нет. У него есть шанс 1 на 63 КБ. Чего вы не увидите, так это * двух * таких УСТАНОВЛЕННЫХ * соединений: это невозможно по правилам TCP.

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