Вчера при отладке в кластере hadoop заметил кое-что странное
# netstat -taupen | grep 54310
tcp 0 0 10.0.12.209:54310 10.0.12.209:54310 TIME_WAIT
Вы можете заметить, что исходный ip: порт такой же, как целевой ip: порт. Как это возможно. Может ли кто-нибудь объяснить мне, как все работает на уровне tcp, чтобы это соединение работало?
Возможно, потому что было два процесса (предположительно из форка). Левая сторона - это клиент (который вызвал bind (2), чтобы установить исходный IP-адрес и порт, что обычно не выполняется), а правая сторона - это сервер.
Это один из методов достижения IPC (межпроцессного взаимодействия).
Самый распространенный способ установить TCP-соединение - использовать трехстороннее рукопожатие, состоящее из:
Но это не единственный способ установить TCP-соединение. Чтобы установить TCP-соединение, каждая сторона должна отправить SYN, который другой стороне необходимо для ACK, но не требуется, чтобы одна сторона объединяла SYN и ACK в одном пакете. В равной степени возможно четырехстороннее рукопожатие, при котором каждая конечная точка отправляет SYN, а затем каждая конечная точка отправляет ACK.
Одним из вариантов использования этого 4-стороннего рукопожатия является установление соединения между парой хостов, которые оба находятся за межсетевым экраном. Это может быть полезно, если вы запускаете одноранговые приложения в сети, защищенной брандмауэром. Каждая конечная точка будет отправлять SYN и повторно передавать его, пока не будет получен ответ. Это означает, что брандмауэр на каждом конце соединения будет видеть, что локальная конечная точка отправляет пакеты SYN, и как только он увидит такой исходящий пакет, он позволит проходить пакетам SYN и ACK с другого конца. (Хотя этот метод работает как с TCP, так и с UDP, на практике он редко используется с TCP.)
Все это означает для вашего сценария то, что если приложение создает сокет TCP и связывает его с локальным IP-адресом и номером порта, а затем пытается подключиться к тому же IP-адресу и номеру порта, уровень TCP сначала сгенерирует SYN пакет, который доставляется самому себе, а затем отвечает на него ACK, который также доставляется самому себе.
В результате сокет TCP может быть подключен к самому себе, а для уровня TCP это выглядит как четырехстороннее рукопожатие.
Я не знаю, есть ли какое-либо полезное назначение для такого TCP-сокета, подключенного к самому себе, но это то, что могло бы создать соединение, подобное тому, которое было в вашем случае.