betacode

Руководство Java DatagramChannel

View more Tutorials:

Следуйте за нами на нашей фан-странице, чтобы получать уведомления каждый раз, когда появляются новые статьи. Facebook

1- DatagramChannel

DatagramChannel - это класс, который представляет открытое соединение с сетевым сокетом (network socket) и использует протокол UDP/IP для чтения или записи данных в сеть (network).

public abstract class DatagramChannel
    extends AbstractSelectableChannel
    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
UDP

​​​​​​​User Datagram Protocol (UDP) (Протокол пользовательских дейтаграмм): Короче говоря, UDP - это протокол с правилами разделения данных на небольшие пакеты, называемые Datagram у отправителя, и правилами их объединения у получателя. UDP подходит для передачи данных по сети в приложениях, требующих низкой задержки.
1 Datagram = 1 Gram of data (1 грамм данных). Datagram не имеет количественного значения. Его размер не является фиксированным и предназначен только для очень небольшого пакета данных.
UDP/IP
Правил, установленных UDP, недостаточно для передачи данных между 2 устройствами, поэтому их необходимо объединить с Internet (Internet Protocol - IP). И у нас есть протокол UDP/IP:
  • Internet Protocol (IP): Помогает определять местоположение устройств в сети и передавать пакеты данных через Internet. В частности, в этом случае он будет передавать пакеты Datagram.
Пакеты данных, отправляемые по протоколу UDP/IP, не содержат информации о последовательности и не проверяются, поступают ли они по назначению. При таком простом способе отправки UDP/IP быстрее, но менее надежен, чем другие протоколы, такие как TCP/IP. Эта скорость делает компромисс. Если пакет данных будет потерян при передаче, он не будет отправлен повторно. Поэтому приложения, использующие UDP, должны быть способны переносить ошибки, потери и дублирование.
Технически потеря данных не является уязвимостью в UDP. Причиной этого обычно является качество сетевой инфраструктуры, сетевых маршрутизаторов,...
Примеры нескольких типов сервисов, которые обычно используют UDP:
UDP - это идеальный протокол для сетевых приложений, требующих низкой задержки, таких как игры, голосовая и видеосвязь. Эти примеры могут привести к некоторой потере данных без отрицательного влияния на воспринимаемое качество. Однако в некоторых случаях в дополнение к UDP используются методы прямого исправления ошибок для улучшения качества звука и видео, несмотря на некоторые потери.
Смотрите более подробные статьи об UDP/IP и TCP/IP:
Иерархия классов и интерфейсов связана с классом DatagramChannel:

2- Например

В этом примере мы отправим сообщение между 2 программами, запущенными на 2 разных компьютерах. Вот иллюстрация примера:
ReceiverProgram: Программе-получателю необходимо открытьDatagramChannel и прослушать его IP-адрес с определенным портом (port), например "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: Программе-отправителю (сообщению) необходимо открыть DatagramChannel и отправить сообщение на адрес прослушивания программы-получателя (ReceiverProgram).
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();
    }
}
Чтобы протестировать приложение, вам необходимо сначала запустить класс ReceiverProgram, а затем запустить класс SenderProgram:
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

Статические заводские методы:

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
Методы, унаследованные от интерфейсов ReadableByteChannel и WriteableChannel:

public abstract int read(ByteBuffer dst) throws IOException;  
public abstract int write(ByteBuffer src) throws IOException;
Методы, унаследованные от интерфейсов ScatteringByteChannel и GatheringByteChannel:

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
Методы, унаследованные от интерфейса SelectableChannel:

public final int validOps()
  • TODO Link?
Методы, унаследованные от интерфейсов NetworkChannel и MulticastChannel:

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;
Другие методы:

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: