Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Сетевые Технологии > Странности соединения


Автор: Fester 22.03.18, 15:08
Есть у меня клиент-серверное приложение.

Запускаю сервер и клиента на одной машине.

И дальше варианты:
1) На клиенте указываю сервер как 127.0.0.1 и говорю, что клиент должен коннектиться от имени 127.0.0.2 -> все работает.
2) На клиенте указываю сервер как 127.0.0.1 и говорю, что клиент должен коннектиться от имени 192.168.10.100 -> "No connection could be made because the target machine actively refused it."
3) На клиенте указываю сервер как 192.168.10.100 и говорю, что клиент должен коннектиться от имени 127.0.0.2 -> "No connection could be made because the target machine actively refused it."
4) На клиенте указываю сервер как 192.168.10.100 и говорю, что клиент должен коннектиться от имени 192.168.10.100 -> все работает.

Это какая-то особенность TCP? Где про этот эффект можно почитать?

Автор: Pavia 22.03.18, 17:34
Цитата Fester @
"No connection could be made because the target machine actively refused it."

Это шуточки фаервола.
ОС у вас какая?

Автор: Akina 22.03.18, 19:01
Нет тут никакого "эффекта". Основы маршрутизации - узлы из разных подсетей не могут общаться напрямую.

Автор: Fester 22.03.18, 19:25
OS - Win7, также ещё на Win10 или Win Server 2012.


Akina, а как сделать, чтобы все работало? :)

Автор: Akina 22.03.18, 19:27
У тебя два рабочих набора настроек - какого тебе ещё надо-то?

Кстати, раз это всё происходит на одном инстансе ОС, то первый вариант предпочтителен.

Автор: Oleg2004 22.03.18, 20:45
Цитата Fester @
No connection could be made because the target machine actively refused it."

Это ошибка 10061.
И как видно по ошибке, сервер таки получает SYN от клиента, но отвечает RST. Не хочет ставить запрос в очередь.
Т.е. сервер ВИДИТ клиента, SYN сегмент до него доходит.
Вариантов тут много, вот тут http://rsdn.org/forum/network/1365288.flat они обсуждаются.
Один из вариантов - на сервере мала очередь входящих запросов.
Вот еще один вариант http://www.php.su/forum/topic.php?forum=1&topic=8042
Еще один вариант - это тот о котором говорит Акина. Стек TCP/IP лакальной машины ведь ОДИН и тот же, а его заставляют работать в разных подсетях...хотя что до меня так это проблематично - так как сервер все таки видит клиента, если шлет ему RST.
В общем вариантов много.
Еще одна фишка именно с отладкой на одной и той же машине клиента и сервера. Во все функции коннекта, приема передачи и тд надо вставлять SLEEP()на миллисекунд 50 примерно чтобы не заставлять стек корячиться одновременно с двумя сетевыми приложениями. Т.е. простое моделирование обычных задержек в реальной сети.

Автор: Pavia 22.03.18, 21:56
Fester
Просто в свойствах брандмауэра пропишите нужные адреса. Дело в том что из локальной сети в частные закрыт видимо в целях безопасности. Нужно явно прописать 127.0.0.1/24
Учтите что это надо сделать для обоих профилей "частный" и "общий" (или "все")

Пуска -> панель управления ->администрирование -> Монитор брандмауэра Защитника Windows в режиме повышенной безопасности

user posted image

Автор: Fester 23.03.18, 07:46
Прошу прощение, я скопировал не то сообщение :blush:

1) На клиенте указываю сервер как 127.0.0.1 и говорю, что клиент должен коннектиться от имени 127.0.0.2 -> все работает.
2) На клиенте указываю сервер как 127.0.0.1 и говорю, что клиент должен коннектиться от имени 192.168.10.100 -> "The requested address is not valid in its context 127.0.0.1:4001" (код ошибки 10049)
3) На клиенте указываю сервер как 192.168.10.100 и говорю, что клиент должен коннектиться от имени 127.0.0.2 -> "A socket operation was attempted to an unreachable network. 192.168.10.100:4001" (код ошибки 10051)
4) На клиенте указываю сервер как 192.168.10.100 и говорю, что клиент должен коннектиться от имени 192.168.10.100 -> все работает.

Автор: Akina 23.03.18, 08:33
Я только не понимаю, почему ты не используешь самый очевидный в режиме одного инстанса ОС вариант - и клиент, и сервер с адресом 127.0.0.1... зачем нужен этот выверт с 127.0.0.2?

Автор: Fester 23.03.18, 09:02
Там нет разницы 127.0.0.1 или 127.0.0.2

Ну а 127.0.0.2 использую, просто потому что мне надо симулировать много клиентов (клиентов мы различаем по IP) и если сервер крутится на 127.0.0.1, то симулировать 10 клиентов я смогу просто отправляя сообщения с адресов 127.0.0.1, 127.0.0.2, ..., 127.0.0.10

В принципе я могу добавить логику и если сервер указан как 127.*.*.*, то не показывать все остальные IP (кроме 127.*.*.*), а если указан любой другой IP, то я буду брать IPшники с адаптора. Собственно говоря подозреваю, что именно так и надо будет сделать... но шеф хочет объяснения, почему это так.

Автор: Akina 23.03.18, 09:47
Цитата Fester @
шеф хочет объяснения, почему это так

Ну потыкай его носом в основы маршрутизации, что ли... узел может напрямую общаться только с узлом из той же подсети (и то - с исключениями), для остальных необходимо наличие маршрутизирующего шлюза. А адреса 127.0.0.1 и 192.168.10.100 могут быть в одной подсети, только если это сеть 0.0.0.0/0, чего операционная система тупо не примет...

Автор: ^D^ima 23.03.18, 09:48
Цитата Fester @
127.0.0.1

Это отдельный виртуальный интерфейс для проверки сетевого стека, он не маршрутизируется с реальными интерфейсами, смотри таблицу маршрутизации.
127.0.0.1 это адрес и интерфейс. А так-же любой адрес подсети 127.x.x.x принадлежит интерфейсу 127.0.0.1.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    IPv4 таблица маршрута
    ===========================================================================
    Активные маршруты:
    Сетевой адрес           Маска сети      Адрес шлюза       Интерфейс  Метрика
              0.0.0.0          0.0.0.0      10.10.1.200       10.10.1.46     20
            10.10.1.0    255.255.255.0         On-link        10.10.1.46    276
           10.10.1.46  255.255.255.255         On-link        10.10.1.46    276
          10.10.1.255  255.255.255.255         On-link        10.10.1.46    276
            127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
            127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
      127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
         192.168.56.0    255.255.255.0         On-link      192.168.56.1    266
         192.168.56.1  255.255.255.255         On-link      192.168.56.1    266
       192.168.56.255  255.255.255.255         On-link      192.168.56.1    266
            224.0.0.0        240.0.0.0         On-link         127.0.0.1    306
            224.0.0.0        240.0.0.0         On-link        10.10.1.46    276
            224.0.0.0        240.0.0.0         On-link      192.168.56.1    266
      255.255.255.255  255.255.255.255         On-link         127.0.0.1    306
      255.255.255.255  255.255.255.255         On-link        10.10.1.46    276
      255.255.255.255  255.255.255.255         On-link      192.168.56.1    266
    ===========================================================================

Автор: Akina 23.03.18, 09:58
Цитата ^D^ima @
Это отдельный виртуальный интерфейс для проверки сетевого стека

Если с первой половиной согласен, то вот вторая - насчёт "для проверки",- вызывает определённые сомнения.
И ещё я дополнительно бы указал, что любой сетевой узел имеет такой внутренний интерфейс. Т.е. любое обращение к нему - это обращение к себе, а не наружу...

Автор: Fester 23.03.18, 10:07
Цитата ^D^ima @
смотри таблицу маршрутизации

Мне это ни о чем не говорит :)

Цитата ^D^ima @
127.0.0.1 это адрес и интерфейс.

В твоем списке одинаковая картина для 10.10.1.46, 127.0.0.1 и 192.168.56.1 Значит ли это, что с 10.10.1.46 можно обращаться к 127.0.0.1 или к 192.168.56.1 и обратно? Или для того, чтобы можно было установить соединение должен быть один и тот же интерфейс?

Посмотрел у себя - тоже самое - 10.2.5.1 - это и адрес и интерфейс, также как и 127.0.0.1. Связи нет.

Автор: Oleg2004 23.03.18, 10:10
^D^ima
В принципе можно было бы с вами согласиться.
Но ведь SYN от клиента приходит к серверу и наоборот от сервера приходит RST.
И занимается этой рассылкой ОДИН и ТОТ же стек.
Поэтому скорее всего я бы посчитал такое поведение особенностью стека TCP/IP - стек понимает бессмысленность обмена между реальным и виртуальным интерфейсами. Потому и RST. Имхо.

Автор: Akina 23.03.18, 10:44
Цитата Fester @
В твоем списке одинаковая картина для 10.10.1.46, 127.0.0.1 и 192.168.56.1

Что интерфейсы разные - не заметил, что ли?

Автор: Fester 23.03.18, 10:49
Цитата Akina @
Что интерфейсы разные - не заметил, что ли?

Заметил. Дописал потом ;)

Я так понимаю, что если разные интерфейсы, то надо вносить изменения в таблицу маршрутизации?

Автор: Akina 23.03.18, 10:56
Цитата Oleg2004 @
скорее всего я бы посчитал такое поведение особенностью стека TCP/IP

Допустим, мы (у Димы на компе - он показал таблицу рутинга) попробуем от имени 127.0.0.1 общаться с 10.10.1.46. Стек получает команду на операцию. В узел назначения он находит маршрут - через 10.10.1.46. Этот адрес шлюза не находится в одной подсети с 127.0.0.1. Пересылка пакета невозможна.
Теперь наоборот - попробуем от имени 10.10.1.46 общаться с 127.0.0.1. Стек получает команду на операцию. Узел назначения он определяет как локальный, для которого запрещена маршрутизация (емнип по стандарту любой маршрутизатор обязан такой пакет дропнуть либо отбить), такой узел не может работать с внешними адресами. Пересылка пакета невозможна.
Я бы скорее обратную картину посчитал расширением поведения стека, а наблюдаемое - нормой.

Добавлено
Цитата Fester @
если разные интерфейсы, то надо вносить изменения в таблицу маршрутизации?

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

Автор: Oleg2004 23.03.18, 12:18
Цитата Akina @
Пересылка пакета невозможна.

Я такого объяснения не принимаю.
А может и не понимаю :D
Еще раз повторю:
Цитата
Но ведь SYN от клиента приходит к серверу и наоборот от сервера приходит RST.

Итак, пересылка TCP-сегментов ОСУЩЕСТВЛЯЕТСЯ.
Их - два. Туда - SYN и обратно - RST.
Убедите меня в обратном.
Если маршрут до сервера невозможно проложить, ошибка была бы из разряда Host Unreachable
И никакого RST клиент не получил бы ваще.

Автор: ^D^ima 23.03.18, 12:45
Цитата Akina @
насчёт "для проверки",- вызывает определённые сомнения.

Кстати да, не только для этого :)
Как раз для вариантов клиент-сервер на 1 ПК и используется, Fester

Автор: Akina 23.03.18, 19:03
Цитата Oleg2004 @
Если маршрут до сервера невозможно проложить, ошибка была бы из разряда Host Unreachable

Это ошибка, специфичная для ICMP. И я убеждён, что если бы пробовался не TCP-коннект, а тупо пинг, то было бы получено либо Unreachable, либо вообще General Failure.

Автор: Oleg2004 23.03.18, 19:42
Да, наверно вы правы что это специфично, но не для ICMP, а для ошибки маршрутизации в реальной сети. ICMP просто протокол для передачи подобных сообщений.
Наверно поэтому такой ошибки и не может быть в пределах одного хоста.
Однако признайте тот факт, что сервер все таки получает SYN клиента.
А значит маршрутизация внутри хоста тут совсем не причем...
Как то вы все явно не реагируете на этот очевидный факт :wall:

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)