Излъчване и Multicasting в Java

1. Въведение

В тази статия ние описваме как комуникациите „един към всички“ (Broadcast) и „one-to-many“ (Multicast) могат да бъдат обработвани в Java. Концепциите за излъчване и мултикаст, описани в тази статия, се основават на UDP протокола.

Започваме с бързо обобщение на дейтаграми и излъчване и как се прилага в Java. Ние също така разглеждаме недостатъците на излъчването и предлагаме разпръскване като алтернатива на излъчването.

Накрая завършваме, като обсъждаме подкрепата за тези два метода за адресиране както в IPv4, така и в IPv6.

2. Обобщение на дейтаграмата

Според официалната дефиниция на дейтаграма, „Дейтаграмата е независимо, самостоятелно съобщение, изпратено по мрежата, чието пристигане, време на пристигане и съдържание не са гарантирани“.

В Java пакетът java.net излага класовете DatagramPacket и DatagramSocket , които могат да се използват за комуникация чрез UDP протокола. UDP обикновено се използва в сценарии, при които по-ниската латентност е по-важна от гарантираната доставка, като аудио / видео стрийминг, откриване на мрежа и т.н.

За да научите повече за UDP и дейтаграмите в Java, вижте Ръководство за UDP в Java.

3 . Излъчване

Излъчването е един-за-всички тип комуникация, т.е. намерението е да се изпрати дейтаграмата до всички възли в мрежата. За разлика от случая на комуникация от точка до точка, ние не трябва да знаем IP адреса на целевия хост . Вместо това се използва излъчен адрес.

Съгласно протокола IPv4, излъчваният адрес е логичен адрес, на който устройствата, свързани към мрежата, имат възможност да получават пакети. В нашия пример използваме определен IP адрес, 255.255.255.255 , който е излъченият адрес на локалната мрежа.

По дефиниция маршрутизаторите, свързващи локална мрежа с други мрежи, не препращат пакети, изпратени до този адрес по подразбиране. По-късно ние също така показваме как можем да итерираме през всички мрежови интерфейси и да изпращаме пакети до съответните им адреси за излъчване.

Първо, ние демонстрираме как да излъчваме съобщение. До тази степен трябва да извикаме метода setBroadcast () в сокета, за да знаем, че пакетът ще бъде излъчен:

public class BroadcastingClient { private static DatagramSocket socket = null; public static void main((String[] args)) throws IOException { broadcast("Hello", InetAddress.getByName("255.255.255.255")); } public static void broadcast( String broadcastMessage, InetAddress address) throws IOException { socket = new DatagramSocket(); socket.setBroadcast(true); byte[] buffer = broadcastMessage.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 4445); socket.send(packet); socket.close(); } }

Следващият фрагмент показва как да прегледате всички NetworkInterfaces, за да намерите адреса им за излъчване:

List listAllBroadcastAddresses() throws SocketException { List broadcastList = new ArrayList(); Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface networkInterface = interfaces.nextElement(); if (networkInterface.isLoopback() || !networkInterface.isUp()) { continue; } networkInterface.getInterfaceAddresses().stream() .map(a -> a.getBroadcast()) .filter(Objects::nonNull) .forEach(broadcastList::add); } return broadcastList; }

След като имаме списъка с адреси за излъчване, можем да изпълним кода в метода за излъчване () , показан по-горе за всеки от тези адреси.

Не се изисква специален код от приемащата страна за получаване на излъчено съобщение. Можем да използваме повторно същия код, който получава нормална UDP дейтаграма. Ръководство за UDP в Java съдържа повече подробности по тази тема.

4. Мултикастиране

Излъчването е неефективно, тъй като пакетите се изпращат до всички възли в мрежата, независимо дали те се интересуват от получаването на комуникацията или не. Това може да е загуба на ресурси.

Мултикастирането решава този проблем и изпраща пакети само на тези потребители, които се интересуват. Мултикастирането се основава на концепция за членство в група , където мултикаст адрес представлява всяка група.

В IPv4 всеки адрес между 224.0.0.0 до 239.255.255.255 може да се използва като адрес за мултикаст. Само онези възли, които са абонирани за група, получават пакети, съобщени на групата.

В Java MulticastSocket се използва за получаване на пакети, изпратени до мултикаст IP. Следващият пример демонстрира използването на MulticastSocket :

public class MulticastReceiver extends Thread { protected MulticastSocket socket = null; protected byte[] buf = new byte[256]; public void run() { socket = new MulticastSocket(4446); InetAddress group = InetAddress.getByName("230.0.0.0"); socket.joinGroup(group); while (true) { DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String( packet.getData(), 0, packet.getLength()); if ("end".equals(received)) { break; } } socket.leaveGroup(group); socket.close(); } }

След обвързването на MulticastSocket с порт, извикваме метода joinGroup () , като IP аргументът е многоадресен. Това е необходимо, за да можете да получавате пакетите, публикувани в тази група. Методът LeaveGroup () може да се използва за напускане на групата.

Следващият пример показва как да публикувате в IP адрес за многоадресно предаване:

public class MulticastPublisher { private DatagramSocket socket; private InetAddress group; private byte[] buf; public void multicast( String multicastMessage) throws IOException { socket = new DatagramSocket(); group = InetAddress.getByName("230.0.0.0"); buf = multicastMessage.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 4446); socket.send(packet); socket.close(); } }

5. Излъчване и IPv6

IPv4 поддържа три вида адресиране: едноадресен, излъчен и многоадресен. На теория излъчването е комуникация едно към всички, т.е. пакет, изпратен от устройство, има потенциал да достигне до целия Интернет.

Тъй като това е нежелано по очевидни причини, обхватът на излъчването на IPv4 беше значително намален. Multicast, който служи и като по-добра алтернатива на излъчването, се появи много по-късно и следователно изостава в приемането.

В IPv6 поддръжката на мултикаст е направена задължителна и няма изрична концепция за излъчване. Многоадресното предаване е разширено и подобрено, така че всички функции за излъчване вече могат да бъдат внедрени с някаква форма на многоадресно предаване.

В IPv6 най-левите битове на адрес се използват за определяне на неговия тип. За многоадресен адрес първите 8 бита са всички, т.е. FF00 :: / 8. Освен това бит 113-116 представлява обхвата на адреса, който може да бъде един от следните 4: Глобално, локално на сайта, локално на връзката, локално на възел.

В допълнение към unicast и multicast, IPv6 също поддържа anycast, в който пакет може да бъде изпратен до всеки член на групата, но не е необходимо да се изпраща до всички членове.

6. Обобщение

В тази статия разгледахме концепциите за тип комуникация един към всички и един към много, използвайки UDP протокола. Видяхме примери за това как да приложим тези концепции в Java.

И накрая, ние също проучихме поддръжката на IPv4 и IPv6.

Пълен примерен код е достъпен в Github.