codestory

Die Anleitung zu Java DatagramChannel

View more Tutorials:

Folge uns auf unserer fanpage, um jedes Mal benachrichtigt zu werden, wenn es neue Artikel gibt. Facebook

1- DatagramChannel

DatagramChannel ist eine Klasse, die eine offene Verbindung zu einem Netzwerk-Socket darstellt und das UDP/IP-Protokoll verwendet, um Daten im Netzwerk zu lesen oder zu schreiben.

public abstract class DatagramChannel
    extends AbstractSelectableChannel
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
UDP
User Datagram Protocol (UDP): Kurz gesagt, UDP ist ein Protokoll mit Regeln zum Aufteilen von Daten in kleine Pakete namens Datagram(s) beim Sender und Regeln zum Verketten dieser beim Empfänger. UDP eignet sich für die Datenübertragung über das Netzwerk in Anwendungen, die eine geringe Latenz erfordern.
1 Datagram = 1 Gram of data. Datagram hat keine quantitative Bedeutung. Seine Größe ist nicht festgelegt und soll nur ein sehr kleines Datenpaket sein.
UDP/IP
Die von UDP festgelegten Regeln reichen nicht aus, um Daten zwischen 2 Geräten zu senden, daher muss es mit Internet (Internet Protocol - IP) kombiniert werden. Und wir haben das Protokoll UDP/IP:
  • Internet Protocol (IP): Hilft, den Standort von Geräten im Netzwerk zu bestimmen und Datenpakete über das Internet zu transportieren. Insbesondere in diesem Fall wird es Datagramm Pakete transportieren.
Über UDP/IP gesendete Pakete haben keine Sequenzinformationen und werden nicht überprüft, ob sie wie beabsichtigt ankommen. Bei einer so einfachen Art des Sendens ist UDP/IP schneller, aber weniger zuverlässig als andere Protokolle wie TCP/IP. Diese Geschwindigkeit macht einen Kompromiss. Wenn ein Datenpaket während der Übertragung verloren geht, wird es nicht erneut gesendet. Daher müssen Anwendungen, die UDP verwenden, in der Lage sein, Fehler, Verluste und Duplizierungen zu tolerieren.
Technisch gesehen ist Datenverlust keine Schwachstelle in UDP. Ursache dafür ist meist die Qualität der Netzwerkinfrastruktur, Netzwerkrouter,...
Beispiele für einige Arten von Diensten, die häufig UDP verwenden:
UDP ist ein ideales Protokoll für Netzwerkanwendungen, die eine geringe Latenz erfordern, wie beispielsweise in der Spiele-, Sprach- und Videokommunikation. Diese Beispiele können einen gewissen Datenverlust erleiden, ohne die wahrgenommene Qualität zu beeinträchtigen. In einigen Fällen werden jedoch zusätzlich zu UDP Vorwärtsfehlerkorrekturtechniken verwendet, um die Audio- und Videoqualität trotz einiger Verluste zu verbessern.
Lesen Sie ausführlichere Artikel zu UDP/IP und TCP/IP:
Die Hierarchie von Klassen und Interface bezieht sich auf die Klasse DatagramChannel:

2- Zum Beispiel:

In diesem Beispiel senden wir eine Nachricht zwischen 2 Programmen, die auf 2 verschiedenen Computern ausgeführt werden. Hier ist eine Illustration des Beispiels:
ReceiverProgram: Das empfangende Programm muss einen DatagramChannel öffnen und an seiner IP-Adresse mit einem bestimmten Port lauschen, zum Beispiel "localhost:9999".
ReceiverProgram.java

package org.o7planning.datagramchannel.ex;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class ReceiverProgram {

    public static DatagramChannel startReceiver() throws IOException {
        DatagramChannel receiver = DatagramChannel.open();
        // Listening SocketAddress
        InetSocketAddress address = new InetSocketAddress("localhost", 9999);
        receiver.bind(address); // The receiver is listening at localhost:9999

        System.out.println("Receiver started at #" + address);
        return receiver;
    }

    public static String receiveMessage(DatagramChannel receiver) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        SocketAddress senderAddress = receiver.receive(buffer);
        String message = extractMessage(buffer);
        System.out.println("Received message from sender: " + senderAddress);
        return message;
    }

    private static String extractMessage(ByteBuffer buffer) {
        buffer.flip();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        String msg = new String(bytes);
        return msg;
    }

    public static void main(String[] args) throws IOException {
        DatagramChannel receiver = startReceiver();
        while (true) {
            String message = receiveMessage(receiver);
            System.out.println(" - Message: " + message);
            if("Bye!".equals(message)) {
                break;
            }
        }
        receiver.close();
        System.out.println("Receiver closed!");
    }
}
SenderProgram: Das sendende Programm (Nachricht) muss einen DatagramChannel  öffnen und die Nachricht an die Abhöradresse des empfangenden Programms (ReceiverProgram). senden.
SenderProgram.java

package org.o7planning.datagramchannel.ex;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;

public class SenderProgram {

    public static DatagramChannel startSender() throws IOException {
        DatagramChannel sender = DatagramChannel.open();
        // SocketAddress
        SocketAddress address = null;
        sender.bind(address);

        sender.configureBlocking(false);
        return sender;
    }
    public static void sendMessage(DatagramChannel sender, String msg, //
            SocketAddress receiverAddress) throws IOException {
        ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());
        sender.send(buffer, receiverAddress);
    }
    public static void main(String[] args) throws IOException, InterruptedException {
        DatagramChannel sender = startSender();

        String[] messages = new String[] { "Hello", "How are you?", "Bye!" };
        // SocketAddress of the Receiver.
        InetSocketAddress receiverAddress = new InetSocketAddress("localhost", 9999);

        for (String message : messages) {
            // Send message to the Receiver!
            sendMessage(sender, message, receiverAddress);
            Thread.sleep(2 * 1000); // 2 seconds.
        }
        sender.close();
    }
}
Um die Anwendung zu testen, müssen Sie zuerst die Klasse ReceiverProgram und dann die Klasse SenderProgram ausführen:
Output:

Receiver started at #localhost/127.0.0.1:9999
Received message from sender: /127.0.0.1:58179
 - Message: Hello
Received message from sender: /127.0.0.1:58179
 - Message: How are you?
Received message from sender: /127.0.0.1:58179
 - Message: Bye!
Receiver closed!

3- Static Factory methods

Statische Fabrikmethoden:

public static DatagramChannel open() throws IOException  
public static DatagramChannel open(ProtocolFamily family) throws IOException

4- Methods


public abstract class DatagramChannel
    extends AbstractSelectableChannel
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
Methoden, die von Interface ReadableByteChannel und WriteableChannel geerbt werden:

public abstract int read(ByteBuffer dst) throws IOException;  
public abstract int write(ByteBuffer src) throws IOException;
Die Methoden, die von die Interface ScatteringByteChannel und GatheringByteChannel geerbt werden:

public abstract long read(ByteBuffer[] dsts, int offset, int length) throws IOException;  
public final long read(ByteBuffer[] dsts) throws IOException  

public abstract long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
public final long write(ByteBuffer[] srcs) throws IOException
Methoden, die von der Interface SelectableChannel geerbt werden:

public final int validOps()
  • TODO Link?
Von den Interface NetworkChannel und MulticastChannel geerbte Methoden:

public abstract SocketAddress getLocalAddress() throws IOException;
public abstract DatagramChannel bind(SocketAddress local) throws IOException;
public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value) throws IOException;

MembershipKey join(InetAddress group, NetworkInterface interf) throws IOException;
MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source) throws IOException;
Die andere Methode:

public abstract DatagramSocket socket();
public abstract boolean isConnected();
public abstract DatagramChannel connect(SocketAddress remote) throws IOException;
public abstract DatagramChannel disconnect() throws IOException;
public abstract SocketAddress getRemoteAddress() throws IOException;
public abstract SocketAddress receive(ByteBuffer dst) throws IOException;
public abstract int send(ByteBuffer src, SocketAddress target) throws IOException;

View more Tutorials: