2 Gniazdka i datagramy UDP
Zawartość
Protokół UDP Klasa
DatagramPacket Klasa
DatagramSocket
Gniazda Multicast
Cechy protokołu UDP
Protokół bezpołączeniowy oparty o IP
Ograniczona wielkość pakietu - do 65 536 - 8 bajtów na nagłówek
Pole długości datagramu ograniczone od 65 467 do 65 507 bajtów (wielkość datagramu IP)
W praktyce 8192 bajty (8 kB) i mniej (512bajtów)
Datagramy w Java
Protokół UDP w Java jest obsługiwany przez instancję klasy DatagramPacket
(public finał class DetagramPackiet extends Object)
Dostarcza metod do:
Pobierania i ustawiania adresu źródłowego
i docelowego
Wysyłania i odbierania danych
Sprawdzanie i ustawianie długości danych
Konstruktory Datagramów
W odniesieniu do datagramów konstruktory
pozwalają na odbiór i wysyłanie danych
Konstruktory te przyjmują parametry w postaci
tablicy bajtowej przechowującej dane.
Następne dwa konstruktory służą do tworzenia
gniazd do przesyłania danych
Konstruktory do odbioru danych
public DatagramPacket (byte [] buffer, int length)
public DatagramPacket (byte [] buffer, int offset, int length)
Tworzą obiekty DatagramPacket do odbioru danych z sieci.
byte [] buffer - new byte [8192];DatagramPacket dp = new DatagramPackettbuffer, buffer. length)
Konstruktory do wysyłania
danych
public DatagramPacket (byte [] data, int length,
InetAddres destination, int port)
public DatagramPacket (byte [] data, int offset, int length,
InetAddres destination, int port)
Tworzą obiekty DatagramPacket do wysyłania danych przez sieć
Pakiet jest wypełniany length bajtami z tablicy dane zaczynając od indeksu offset (od 0 gdy nie ma offset)
Konstruktory do wysyłania danych - przykład
Strings = "Tojest test;
byte [] data = s.getBytes("ASCII"); try{
InetAddress ia = TnetAddress.getByName ("test.prz-rzeszow.pl"); int port = 7; DatagramPacket dp = new DatagramPacket
(data, data.length, ia, port); //wysylanie pakietu
}Catch (IOException e) { }
Metody get i set
get - klasa DatagramPacket zawiera 5 metod, które zwracają różne części datagramu: rzeczywiste dane oraz kilka pól nagłówka. Stosuje się ją do analizy danych otrzymanych z sieci
set - występuje kilka metod do zmiany danych zdalnego adresu i zdalnego portu już po utworzeniu datagramu. Stosujemy gdy musimy szybko zmienić zawartość pakietu nie tworząc go na nowo.
Metody get
public InetAddress getAddress() - zwraca adres zdalnego host
public byte[] getPort() - zwraca numer portu
public byte[] getData() - zwiera dane zawarte z dekagramie
public int getLength() - zwraca liczbę bajtów danych zawartych w datagramie
public int getOffset() - zwraca indeks od którego zaczynają się dane
Metody set
public InetAddress setAddress (InetAddress remote) - zmienia adres na który będą wysyłane dane
public byte[] setPort() - zmienia port do którego adresowany jest datagram
publuc byte[] setData() - zmienia zawartość detagramu (podmienia dane)
public int setLength() - zmienia liczbę danych w buforze wewnętrznym
Gniazda datagramowe
Aby wysyłać i odbierać dane w sieci
potrzebne jest gniazdo
W tym przypadku jest to gniazdo
datagramowe obsługiwane przez klasę:
public class DatagramSocket extends Object;
Klient - nie musi mieć podanego portu -zostanie przypisany automatycznie
Serwer - musi
Gniazdko serwera i klienta jest identyczne
Konstruktory gniazdek datagramowych
Otwiera gniazdko na anonimowym porcie lokalnym
puhlic DatagramSocket () throws SocketException
To samo gniazdo może odbierać komunikaty od serwera
try{
datagramSocket client = new DetagramSocket(); //Wysyłamy pakiety ...} catch (SockctExccption e){ Systcm.err.println(e);}
Otwiera gniazdko nasłuchujące na porcie o
numerze port.
Stosowany jest do obsługi serwera
Gdy nie uda się utworzyć portu to
generowany jest wyjątek SocketException
public DatagramSocket (int port) throws SocketException
import java.nct.*; public class UDPPortScanner { public static void main(String[] args) for (int port = 1024; port <= 65535; port++) { try{
// następna linia spowoduje błąd i przejdzie do bloku catch // jeśli na porcie działa już jakiś serwer DatagramSockct server = new DatagramSocket(port): serverclose(); //Gdy uda mu się otworzyć to od razu zamyka to co utworzył
catch (Socket Exccption e) {
System.out.println(„Jest już serwer na porcie " + port + "."); } // end try } // end for
}}
Otwiera gniazdko, które oczekuje na przyjście datagramu na określonym interfejsie sieciowym
public DatagramSocket (int port,InetAddress address)
throws SocketException
Aby otworzyć gniazdo poniżej 1024 w Unix trzeba mieć uprawnienia root
Uwaga
Wszystkie 3 konstruktory klasy DatagramSocket
mają do czynienia tylko z lokalnymi adresami i
portami.
Zdalny adres i port są przechowywane w
obiekcie DatagramPacket a nie DataGramSocket
Gniazdo DatagramSocket może wysyłać i
odbierać datagramy od wielu zdalnych hostów.
Wysyłanie i odbieranie datagramów
Podstawowym zadaniem klasy
DatagramSocket jest wysyłanie i
odbieranie danych UDP
Jedno gniazdo może odbierać i wysłać
dane
Może równocześnie wymieniać dane z wieloma różnymi hostami
Wysyłanie datagramów
public void send (DatagramPacket dp) throws SocketException
Do wysyłania danych służy metoda send utworzonego gniazda
theSocket.send (theOutDatagramPacket);
Gdy chcemy wysłać zbyt duży pakiet zjawi się wyjątek IOExceptio
Wysyłanie datagramów - klient
import java.net. *;import java.io.*; public class UDPDiscardClient { public final static int DEFAULT_PORT = 9; public static void main(String[] args) { String hostname; int port = DEFAULT_PORT; if (args.length >0) { hostname = args[0]; try { port = Integer.parseInt(args[l]); } catch (Exccption e) { } }
else {hostname = "localhost";} try {InetAddress server = InetAddress.getByName(hostname);
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket theSocket = new DatagramSocket();
while (true) {
String theLine = userInput.readLine(); if (theLine.equals(".")) break; byte[] data = theLine.getBytes();
DatagramPacket theOutput= new DatagramPacket(data, data.length, server, port); the Socket.send(theOutput); } //end while } // end try
catch (UnknownHostException e) { System.err.println(e); } catch (SocketException se) { System.err.println(se);} catch (IOException e) { System.err.println(e);} } // end main }
Odbieranie datagramów
public void receive (DatagramPacket dp) throws SocketException
Do odbierania danych służy metoda receive utworzonego gniazda
Metoda ta działa podobnie jak access() z klasy ServerSocket blokuje wątek w oczekiwaniu na dane.
Gdy chcemy wysłać zbyt duży pakiet zjawi się wyjątek IOExceptio
Import java.net.*;import java.io.*; public class UDPDiscardServer {
public final static int DEFAULT_PORT = 9;
public finał static int MAX_PACKET_SIZE = 65507;
public static void main(String[] args) { int port = DEFAULT_PORT;
byte[] buffer = new byte[MAX_PACKET_SIZE];
try {port = Integer.parseInt(args[0]); {
catch (Exception e) { }
try{
DatagramSocket server=new DatagramSocket(port); DatagramPacket packet == new DatagramPacket(buffer, buffer.length);
while (true) {
try{
server.receive (packet) ;
String s = new String(packet.getData(), 0, packet.getLength());
System.out.println(packet.getAddress() + " at port " + packetgetPort() + " says " + s); // przywrócenie początkowej długości buforu przed odebraniem następnego pakietu packet.setLength (buffer.length); }
catch (IOExeeption e) { System, err.println(e);} } //end while } // end try
catch (SocketException se) { System.err.println(se); } // end catch } // end main}
Inne metody gniazda
public void close() - zamykanie gniazda
public int getLocalPort() - pobiera numer
lokalnego portu
public void connect(InetAddress host, int port)
- określa adres hosta z którym będzie
wymieniał dane
public void disconnect() - odwraca poprzednią
metodę - może wymieniać dane z dowolnym
hostem
Co to jest multicast?
Jest to transmisja rozgłoszeniowe - grupowa.
Jest to podobne do transmisji radiowej tylko z
określonymi odbiorcami.
Multicast opiera się na protokole UDP
W Java używa się klasy DatagramPacket i
MulticastSocket
Stosowana jest w serwerach DNS, Usnet, w routerach.
Dane są przesyłane pojedynczym strumieniem,
a następnie dzielone na mniejsze strumienie
lokalnie
Dane docierają, do grupy, przesłane im przez
lokalne routery.
Czas życia pakietu TTL (ang. Time-To-Live) -
określa liczbę przeskoków między routerami.
Po osiągnięciu tej liczby pakiet jest odrzucany
Adresy i grupy multicast
Adres multicast to adres grupy hostów z
zakresu: 224.0.0.0 do 239.255.255.255
(klasa D)
Adres ten może być powiązany z nazwą
224.0.1.1- ntp.mcast.net adres rozproszonej
usługi czasowej (ang. Network Time Protocol)
Grupa multicast to zbiór hostów, które
współdzielą jeden adres multicast
Adresy zarezerwowane
224.0.0.l - grupa, która obejmuje hosty w
lokalnej podsieci
224.0.0.0 - 224.0.0.255 - zarezerwowane dla
routerów - trasowanie
224.2.x.x - transmisja dźwięku i obrazu
Zarządzaniem adresami zajmuje się
organizacja IANA
Adresy mogą być stałe lub tymczasowe
Przesyłanie danych multicast
Dane należy umieścić w datagramach multicast i przesłać do grupy za pomocą gniazd multicast
Gniazda multicast zawierają pole TTL
Lokalny host 0
Lokalna podsieć l
Lokalny kampus 16
Szerokopasmowa sieć w USA blisko sieci szkieletowej 32
USA 48
Ameryka Północna 64
Szerokopasmowa sieć światowa 128
Wszystkie sieci na świecie 255
Gniazda multicast
Klasa z pakietu java.net.MulticastSocket
Obsługa tak jak UDP:
-tworzenie bufora
-przygotowanie datagramu
-założenie gniazdka
-wysłanie lub odebranie danych, między czasie dołączenie i odłączenie od grupy
Konstruktory do wysyłania
danych
public MulticastSocket () throws SocketException
public Multicast Socket (int port) throws SocketException
Tworzy gniazdko na animowym porcie i drugi wariant na określonym porcie.
Podłączenie i odłączenie od
grupy
Podłączenie:
public void joinGroupe(InetAdress address) throws IOException
Odłączenie:
public void leaveGroupe(InetAddress address) throws IOException
Wysłanie danych
public void send( DatagramPacket, byte ttl) trows IOException
try {
InetAddres ia =InetAddress.getByName(„experiment.mcast.net");
byte [] data = „Oto dane multicast\r\n" . getBytes();
int port = 4000;
DatagramPacket dp = new DatagramPacket(data,data.length,ia, port)
MulticastSockct ms = new MulticastSocket();
ms.send (dp); // ms.send(dp, 64); -Wysłanie w Ameryce Północnej }
Catch (IOException ie){
System.err.println (ie)}