Я ранее задавал этот вопрос в Stack Overflow, и мне посоветовали переместить вопрос в Server Fault. И вот я здесь :)
Приложение, с которым я работаю, подключается к паре TCP-серверов, работающих на разных компьютерах.
На этот раз мы взяли новую установку Windows на сайт, установили наше приложение, подключили 2 соответствующие сети к клиентскому компьютеру, и в конечном итоге приложение не подключалось к одному из серверов, а другое подключалось просто хорошо. Это снимок экрана с выводом ipconfig:
Сервер, к которому мы не могли подключиться, имел IP-адрес 192.168.3.2
. Клиент, на котором выполнялось приложение, имел IP-адрес 192.168.3.1
.
Мы пробовали пинговать сервер, и это было успешно:
Tracert также добился успеха:
И, наконец, это результат вывода маршрута:
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.42.1 192.168.42.136 291
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
192.168.42.0 255.255.255.0 On-link 192.168.42.136 291
192.168.42.136 255.255.255.255 On-link 192.168.42.136 291
192.168.42.255 255.255.255.255 On-link 192.168.42.136 291
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 192.168.42.136 291
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 192.168.42.136 291
===========================================================================
Persistent Routes:
Network Address Netmask Gateway Address Metric
192.168.3.0 255.255.255.0 192.168.3.1 1
0.0.0.0 0.0.0.0 192.168.42.1 Default
===========================================================================
мы заметили, что журнал клиентского приложения сбрасывал это при попытке подключения: IpUtility.CheckIPRouting IP address 192.168.3.2 incorrectly routed through 192.168.42.136
.
Мы открыли исходный код приложения и заметили, что все, что он делает, это запрашивает интерфейс, используемый для конкретного удаленного IP-адреса (который я не особо понимаю):
Это отрывок из CheckIPRouting
:
public static void CheckIPRouting(IPAddress iPAddressTarget, IPAddress ipAddressGateway)
{
IPEndPoint remoteEndPoint = new IPEndPoint(iPAddressTarget, 0);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress localEndPoint = QueryRoutingInterface(socket, remoteEndPoint);
if (localEndPoint.Equals(ipAddressGateway))
{
log.Trace($"IP address {iPAddressTarget} correctly routed through {localEndPoint.MapToIPv4()}");
}
else
{
log.Debug($"IP address {iPAddressTarget} incorrectly routed through {localEndPoint.MapToIPv4()}");
}
}
А это QueryRoutingInterface
:
private static IPAddress QueryRoutingInterface(Socket socket, IPEndPoint remoteEndPoint)
{
SocketAddress address = remoteEndPoint.Serialize();
byte[] remoteAddrBytes = new byte[address.Size];
for (int i = 0; i < address.Size; i++)
{
remoteAddrBytes[i] = address[i];
}
byte[] outBytes = new byte[remoteAddrBytes.Length];
socket.IOControl(IOControlCode.RoutingInterfaceQuery, remoteAddrBytes, outBytes);
for (int i = 0; i < address.Size; i++)
{
address[i] = outBytes[i];
}
EndPoint ep = remoteEndPoint.Create(address);
return ((IPEndPoint) ep).Address;
}
Позже мы заметили, что в коде клиентского приложения также есть настройка для принудительного подключения через IP-адрес интерфейса с помощью этого кода:
logger.Info("Creating tcpClient for {0} using address {1}", connectionResourceName, adapterAddress);
IPEndPoint adapter = new IPEndPoint(adapterAddress, 0);
tcpClient = new TcpClient(adapter);
Что было хорошо видно в журнале приложения:
Creating tcpClient for RESOURCE using address 192.168.3.1
В этот момент я был сбит с толку. Тогда я решил изменить конфигурацию приложения и вместо использования 192.168.3.1
интерфейс для установки соединения, я изменил адрес интерфейса на 0.0.0.0
.
Тогда связь была установлена!
Печать маршрута в этой точке стала:
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
0.0.0.0 0.0.0.0 192.168.42.1 192.168.42.136 291
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
192.168.3.0 255.255.255.0 On-link 192.168.3.1 2
192.168.3.1 255.255.255.255 On-link 192.168.3.1 257
192.168.3.255 255.255.255.255 On-link 192.168.3.1 257
192.168.42.0 255.255.255.0 On-link 192.168.42.136 291
192.168.42.136 255.255.255.255 On-link 192.168.42.136 291
192.168.42.255 255.255.255.255 On-link 192.168.42.136 291
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 192.168.42.136 291
224.0.0.0 240.0.0.0 On-link 192.168.3.1 257
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 192.168.42.136 291
255.255.255.255 255.255.255.255 On-link 192.168.3.1 257
===========================================================================
Persistent Routes:
Network Address Netmask Gateway Address Metric
192.168.3.0 255.255.255.0 192.168.3.1 1
0.0.0.0 0.0.0.0 192.168.42.1 Default
===========================================================================
Затем я решил вернуть конфигурацию клиентского приложения, чтобы принудительно установить соединение через адаптер 192.168.3.1, как и раньше, и соединение установилось нормально.
Затем я сравнил 2 отпечатка маршрута (до и после). Я заметил следующие новые записи на втором:
192.168.3.0 255.255.255.0 On-link 192.168.3.1 2
192.168.3.1 255.255.255.255 On-link 192.168.3.1 257
192.168.3.255 255.255.255.255 On-link 192.168.3.1 257
224.0.0.0 240.0.0.0 On-link 192.168.3.1 257
255.255.255.255 255.255.255.255 On-link 192.168.3.1 257
Я предполагаю, что все это имеет значение. Но я думал, что постоянный маршрут с этим справится.
Наконец, я подхожу к вопросу:
Почему Windows проигнорировала постоянный маршрут и решила направлять TCP-пакеты через неправильный интерфейс? Как я могу сделать это надежным, чтобы Windows не приняла неправильное решение?
Для справки, это с Windows 10 IoT Enterprise.
Добавленный вами постоянный маршрут не нужен, возможно, неправильный.
Persistent Routes: Network Address Netmask Gateway Address Metric 192.168.3.0 255.255.255.0 192.168.3.1 1
Вы сказали Windows: «Отправляйте все сообщения, адресованные в подсеть 192.168.3.0/24, через шлюз 192.168.3.1».
192.168.3.0/24 напрямую подключена к сети. Вам не нужны никакие маршруты для общения.
Во-первых route print
На выходе не было информации о том, как общаться с сетью 192.168.3.0/24. Это могло быть вызвано отключением интерфейса / отсоединением кабеля. Можете ли вы воспроизвести проблему на другой машине?