Подтвердить что ты не робот

Как вы можете подключить TCP-порт к одному и тому же порту?

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

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

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

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

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

Изменить 01

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

TCP-соединение однозначно идентифицируется с помощью этого набора (local address, local port #, foreign address, foreign port #). Нет требования, чтобы local address и foreign address, или даже номера портов были разными (хотя это было бы чрезвычайно странно). Но есть не более одного 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, хотя в этом случае исходный и чуждый были бы совершенно разными.