Связывание и отправка UDP-сокетов в Windows 1709 - PullRequest
0 голосов
/ 04 октября 2018

Я отлаживал проблему сети UDP на Windows Server 1709, которая сводится к следующему коду:

public class SendUDP {
  public static void main(String[] args) throws IOException {
    byte[] buffer = {0};
    InetAddress address = InetAddress.getByName(args[0]);
    int port = Integer.parseInt(args[1]);

    DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);

    System.out.println("Sending packet to " + packet.getSocketAddress().toString());

    InetSocketAddress localhost = new InetSocketAddress(args[2], 0);
    DatagramSocket datagramSocket = new DatagramSocket(localhost);
    System.out.println("Sending socket bound to " + datagramSocket.getLocalSocketAddress());

    datagramSocket.send(packet);
  }
}

Предполагаемые аргументы: <address to send to> <port to send to> <local address to bind to>.Поэтому все, что это делает, - это создает локально связанный сокет UDP и отправляет на него пакет.

В Linux, Mac и Windows <1709 (рабочая станция 10 и сервер 2016) это работает нормально, если локально связанный адрес равен <code>127.0.0.1 и адрес для отправки - это IP-адрес того же хоста (я просто отправляю пакет локальному процессу). Однако , на сервере 1709 я получаю следующее исключение:

$ java SendUDP 10.128.0.3 500 127.0.0.1
Sending packet to /10.128.0.3:500
Sending socket bound to /127.0.0.1:50209
Exception in thread "main" java.net.SocketException: Network is unreachable: Datagram send failed
        at java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
        at java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:136)
        at java.net.DatagramSocket.send(DatagramSocket.java:693)
        at SendUDP.main(SendUDP.java:20)

В этой системе мне кажется, что я должен убедиться, что я либо привязан ко всем интерфейсам (0.0.0.0), либо к отправляющемуадрес такой же, как связанный адрес.Так, для приведенного выше примера 10.128.0.3 500 0.0.0.0 работает просто отлично.Аналогично, 127.0.0.1 500 127.0.0.1 работает и 10.128.0.3 500 10.128.0.3 также работает.Я проверил это на Java 1.8.1_181.

Я не специалист по сетевым технологиям, но может показаться, что даже когда сокет привязан к какому-либо произвольному локальному адресу, ОС должна иметь возможность маршрутизироватьисходящие пакеты, отправленные на этот сокет, правильно.Это что-то не так в этой версии Windows или мои предположения о неправильной отправке UDP-пакетов?

1 Ответ

0 голосов
/ 05 октября 2018

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

Какойэто на самом деле.Когда сокет локально привязан к 127.0.0.1 явно (или к любому конкретному локальному IP, в этом отношении), этот сокет может отправлять только адресатам, которые доступны сетевым интерфейсом, которому принадлежит IP.

Когдасокет связан с 127.0.0.1 (интерфейс local loopback), доступен только интерфейс loopback (который включает сокеты, связанные с 0.0.0.0 для всех интерфейсов).Это то, для чего предназначен loopback.

Итак, технически исправленная ошибка, вы не должны быть в состоянии отправить на 10.128.0.3, когда явно связаны с 127.0.0.1.Два IP-адреса должны находиться на разных интерфейсах без маршрутизации между ними.Таким образом, эта отправка не должна работать на любой системе при нормальных условиях.

Это что-то не работает в этой версии Windows

Во всяком случае, это звучит как ошибка в старых версиях, которая была исправлена ​​в новой версии.Но это не объясняет, почему он работает на Linux и Mac, потому что не должен работать .Похоже, что 10.128.0.3 каким-то образом отображается на тот же интерфейс loopback, что и 127.0.0.1, или адаптер loopback на некоторых машинах более гибок, чем другие, и допускает маршруты с другими локальными интерфейсами.Таким образом, разрешается связь между 127.0.0.1 и 10.128.0.3.Но это не типичный сценарий.Больше похоже на плохую конфигурацию сети.Интерфейс loopback должен быть изолированным.

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