Как вы можете установить TCP-соединение с тем же портом? - PullRequest
22 голосов
/ 09 февраля 2011

Машина RHEL 5.3 (ядро 2.6.18).

Иногда в netstat я замечаю, что мое приложение имеет соединение, устанавливаемое TCP-соединение, когда Локальный адрес и Внешний адрес совпадают.

Здесь та же проблема, о которой сообщал кто-то другой.

Симптомы те же, что описаны в ссылке - клиент подключается к порту X порта сервера, работающего локально. Через некоторое время netstat показывает, что у клиента есть соединение от 127.0.0.1:X до 127.0.0.1:X

Как это возможно?

Редактировать 01

Одновременное открытие вызывает проблему (большое спасибо Hasturkun). Это можно увидеть на классической диаграмме состояний TCP при переходе из состояния SYN_SENT в состояние SYNC_RECEIVED

Ответы [ 2 ]

18 голосов
/ 09 февраля 2011

Это может быть вызвано одновременным соединением TCP (упомянутое в этом посте к LKML , см. Также здесь ).

Возможно зацикливание программы при попыткедля подключения к порту в динамическом диапазоне локальных портов (который можно увидеть в /proc/sys/net/ipv4/ip_local_port_range), чтобы успешно выполнить, пока сервер не прослушивает этот порт.

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

13 голосов
/ 09 февраля 2011

TCP-соединение однозначно идентифицируется этим кортежем (local address, local port #, foreign address, foreign port #). Не требуется, чтобы local address и foreign address или даже номера портов были разными (хотя это было бы чрезвычайно странно). Но самое большее 1 TCP-соединение имеет одинаковые значения для данного кортежа.

Когда компьютер подключается к себе, его локальный адрес и внешний адрес почти всегда совпадают. В конце концов, «локальная» и «внешняя» стороны - это на самом деле один и тот же компьютер. Фактически, когда это происходит, ваш компьютер должен показывать два соединения, которые имеют одинаковые «локальные» и «чужие» адреса, но поменялись местами номера портов. Например:

$ ssh localhost

приведет к двум соединениям, которые будут выглядеть примерно так:

$ netstat -nA inet | fgrep :22
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address        Foreign Address        State      
tcp        0      0 127.0.0.1:56039      127.0.0.1:22           ESTABLISHED 
tcp        0      0 127.0.0.1:22         127.0.0.1:56039        ESTABLISHED 

Как видите, локальный адрес и внешний адрес совпадают, но номера портов поменялись местами. Уникальный кортеж для этого TCP-соединения (127.0.0.1, 56039, 127.0.0.1, 22). Не будет другого TCP-соединения с такими же четырьмя полями.

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

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

import socket
import time

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 56443))
s.connect(('127.0.0.1', 56443))
time.sleep(30)

Этот код работает, потому что один из способов открыть TCP-соединение состоит в том, чтобы другая сторона соединения пыталась открыть его одновременно с вами. Это известно как одновременный обмен SYN , а связанный с StackOverflow ответ описывает, о чем идет речь.

У меня также есть статья о , использующая одновременный обмен SYN для прохождения через NAT , хотя в этом случае источник и внешний источник будут совершенно разными.

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