Обратите внимание, что в этой теме у плаката, похоже, есть проблема, связанная с моей: Windows против Linux) К сожалению, этот пост умер без какого-либо решения проблемы.
В настоящее время у меня возникают проблемы с Datagramsockets в Java. В целом проблема в том, что у меня есть кусок кода Java, который может получать пакеты в Windows, но не в Linux.
Очень важно, чтобы мое приложение
- Умеет работать как на Windows, так и на Linux. Можно сказать, что мы поддерживаем только Windows 7 и более поздние версии.
- Работает на машинах с несколькими сетевыми интерфейсами. Под этим я подразумеваю, что должна быть возможность указать, с какого сетевого интерфейса приложение должно получать свои пакеты.
Мои тестовые машины
- m1 : Запуск Windows 7 Pro x64 на физическом компьютере. версия Java "1.8.0_45" (Оракул)
- m2: Запуск Centos7 x64 в vmware. Использование версии Java "1.8.0_51" (Oracle)
- m3: Запуск Fedora 19 x64 на физической машине. Использование Java версии 1.7.0_71 (openjdk)
- m4: Запуск Fedora 19 x64 в vmware. версия Java "1.8.0_31"
- m5: Запуск windowsXP x86 на физическом компьютере: на этом компьютере не выполняется моя программа, а вместо этого внешняя система передает пакеты, которые я хочу получать.
- m6: Запуск Windows 7 Pro x64 на физическом компьютере: На этом компьютере запущена не моя программа, а внешняя система, транслирующая пакеты, которые я хочу получать.
В настоящее время моя программа получает пакеты от m5 и m6 на m1, но не на m2, m3 и m4.
В целом логику сокетов в моей программе можно описать следующим образом.
// Setting up the socket
DatagramSocket socket = new DatagramSocket(networkInterfaceAddress, port);
socket.setReceiveBufferSize(90000);
// Setting up the receive packets
DatagramPacket packet = new DatagramPacket(new byte[1], 0);
// Constructing the receive buffer
buffer = new byte[1024]
// Receiving the packet
packet.setData(buffer);
packet.setLength(buffer.length);
socket.receive(packet);
Я пробовал следующее:
- Отключил брандмауэр на всех машинах. это не помогло
- Использовал Wireshark на м2, м3 и м4. Wireshark смог обнаружить пакеты на всех машинах, поэтому они действительно их получают ( 4. также указывает на это)
- Изменил мою тестовую настройку s.t. Вместо этого я транслировал с m2 (используя собственное приложение, а не внешнюю систему). Ни m1, ни m3, ни m4 не смогли получить пакеты. Самое смешное, что мне удалось их увидеть во внешних системах на м5 и м6.
- Переписал логику с.т. Я не указал networkInterfaceAddress в конструкторе для DatagramSocket (поэтому я использовал socket = new DatagramSocket(port);. С этим обновлением я внезапно смог получать пакеты на m2, m3 и m4
4 указывает на то, что проблема связана с networkInterfaceAddress, но если я попытаюсь запустить программу в режиме отладки, я увижу, что networkInterfaceAddress действительно содержит ожидаемое значение. Чтобы быть уверенным, я также попробовал фиктивный пример жесткого кода на m2. В этом фиктивном примере я
- Использовал ifconfig, чтобы увидеть адрес моего сетевого интерфейса. В моем случае ifconfig дал мне инициализацию 10.10.1.41.
- Используется networkInterfaceAddress = InetAddress.getByName("10.10.1.41");
Даже с этим сетевым интерфейсом жесткого кода я не мог получать пакеты.
Так что в настоящее время я могу получать пакеты только в Linux, не предоставляя сетевой интерфейс конструктору DatagramSocket. Проблема с этим решением заключается в том, что (насколько я понимаю) это приведет к тому, что приложение не сможет получать пакеты только с определенного сетевого интерфейса.
Честно говоря, у меня заканчиваются идеи, поэтому я надеюсь, что кто-то сможет помочь мне решить эту проблему.