Как создать входной поток, источником которого является полученный пакет (ByteArrayInputStream и DataInputStream)? - PullRequest
0 голосов
/ 30 апреля 2018

Это часть моего кода (многоадресная подписка на изображения)

public void subscribe() throws IOException {
    byte[] b = new byte[100];
    DatagramPacket datagram = new DatagramPacket(b, b.length, groupAddress, localPort);
    MulticastSocket socket = new MulticastSocket(localPort);
    socket.joinGroup(groupAddress);
    socket.send(datagram);

    while(true) {
      socket.receive(datagram); 
      System.err.println("Received " + datagram.getLength() +
        " bytes from " + datagram.getAddress());
      datagram.setLength(b.length); 
      socket.leaveGroup(groupAddress);
      socket.close();
    }

Вот задача:

Создание входного потока, источником которого является полученный пакет (например, ByteArrayInputStream и DataInputStream).

это издатель:

private void castOneImage (DatagramSocket socket, String imageFn, SocketAddress groupSocketAddress) {

    byte[] imageBytes = null;
    try (InputStream in = getClass().getClassLoader().getResourceAsStream(imageFn);
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) {
        if (in == null) {
            throw new FileNotFoundException("Cannot open image file " + imageFn);
        }
        int b;
        while ((b = in.read()) != -1) {
            byteOut.write(b);
        }
        imageBytes = byteOut.toByteArray();

        byteOut.reset();
        ByteBuffer byteBuffer = ByteBuffer.allocate(Integer.SIZE / 8);
        byteBuffer.putInt(imageBytes.length);
        byteOut.write(byteBuffer.array());
        byteOut.write(imageBytes);
        imageBytes = byteOut.toByteArray();

        DatagramPacket packet = new DatagramPacket(imageBytes, imageBytes.length, groupSocketAddress);
        socket.send(packet);
    } catch (IOException e) {
        // if there is an error for this image, we soldier on hoping other images may be good
        LOGGER.warn("I/O error: " + e.getMessage(), e);
    }
}

1 Ответ

0 голосов
/ 30 апреля 2018

Используйте ByteArrayInputStream:

DataInputStream dis = new DataInputStream(new ByteArrayInputStream(datagram.getData(), datagram.getOffset(), datagram.getLength()));

И переместите close() за пределы цикла. Вам не нужно явно выходить из группы, если вы собираетесь закрыть сокет.

РЕДАКТИРОВАТЬ Чтобы восстановить данные изображения:

int length = dis.readInt();
byte[] image = new byte[length];
dis.readFully(image);

Но, конечно, поскольку дейтаграммы знают свою длину, вам вообще не нужно было отправлять или получать слово length.

...