Подтвердить что ты не робот

Как отправить массив байтов по TCP-соединению (java-программирование)

Может кто-нибудь продемонстрировать, как отправить массив байтов через TCP-соединение из программы-отправителя в программу-приемник в Java.

byte[] myByteArray

(Я новичок в программировании на Java и не могу найти пример того, как это сделать, что показывает оба конца соединения (отправитель и получатель). Если вы знаете существующий пример, возможно, вы могли бы (Нет необходимости изобретать колесо). PS Это НЕ домашнее задание!: -)

4b9b3361

Ответ 1

Классы InputStream и OutputStream в Java обрабатывают массивы байтов. Единственное, что вы можете добавить, это длина в начале сообщения, чтобы получатель знал, сколько байтов ожидать. Обычно мне нравится предлагать метод, который позволяет контролировать, какие байты в массиве байтов отправлять, как и стандартный API.

Что-то вроде этого:

private Socket socket;

public void sendBytes(byte[] myByteArray) throws IOException {
    sendBytes(myByteArray, 0, myByteArray.length);
}

public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
    if (len < 0)
        throw new IllegalArgumentException("Negative length not allowed");
    if (start < 0 || start >= myByteArray.length)
        throw new IndexOutOfBoundsException("Out of bounds: " + start);
    // Other checks if needed.

    // May be better to save the streams in the support class;
    // just like the socket variable.
    OutputStream out = socket.getOutputStream(); 
    DataOutputStream dos = new DataOutputStream(out);

    dos.writeInt(len);
    if (len > 0) {
        dos.write(myByteArray, start, len);
    }
}

EDIT. Чтобы добавить принимающую сторону:

public byte[] readBytes() throws IOException {
    // Again, probably better to store these objects references in the support class
    InputStream in = socket.getInputStream();
    DataInputStream dis = new DataInputStream(in);

    int len = dis.readInt();
    byte[] data = new byte[len];
    if (len > 0) {
        dis.readFully(data);
    }
    return data;
}

Ответ 2

Просто начните с этот пример из Really Big Index. Обратите внимание, что он предназначен для передачи и приема символов, а не байтов. Однако это не имеет большого значения - вы можете иметь дело с необработанными объектами InputStream и OutputStream, которые предоставляет класс Socket. См. API для получения дополнительной информации о различных типах читателей, писателей и потоков. Вам будут интересны методы OutputStream.write(byte[]) и InputStream.read(byte[]).

Ответ 3

Учебное пособие Oracle Socket Communications, похоже, будет подходящей точкой запуска.

Обратите внимание, что это приведет к дополнительной неприятности для превращения символов в байты. Если вы хотите работать на уровне байта, просто очистите его.

Ответ 5

То, что вам нужно использовать, - это метод write метода java.io.OutputStream и read для java.io.InputStream, оба из которых вы можете извлечь из открываемого Socket.

Ответ 6

Я бы попросил вас использовать ObjectOutputStream и ObjectInputStream. Они отправляют все как объект и получают как одно и то же.

ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
os.flush();
ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
os.writeObject(byte_array_that_you_want_to_send);
byte[] temp = (byte[]) is.readObject();

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

Ответ 7

Я предполагаю, что вопрос сформулирован неправильно. Я нашел это при поиске ответа на вопрос, почему мое использование InputStream и OutputStream показало, что весь массив равен 0 при встрече с байтом значения 0. Предположим ли они, что байты содержат действительный ASCII, а не двоичный. Поскольку вопрос не возникает и спрашивает об этом, и никто другой, похоже, не поймал его как возможность, я думаю, мне придется удовлетворить мои поиски в другом месте.

То, что я пытался сделать, это написать класс TransparentSocket, который может создавать прозрачность через TCP (Socket/ServerSocket) или UDP (DatagramSocket) для использования DatagramPacket. Он работает для UDP, но не для TCP.

Последующие действия: я, похоже, подтвердил, что эти потоки сами по себе бесполезны для двоичных передач, но что они могут быть переданы в более удобное для программиста создание экземпляра, например,

новый DataOutputStream (socket.getOutputStream()). writeInt (5);

^ Так много для этой идеи. Он записывает данные "переносимым" способом, то есть, вероятно, ASCII, который вообще не помогает, особенно при эмуляции программного обеспечения, над которым я не контролирую!

Ответ 8

import java.io.*;
import java.net.*;

public class ByteSocketClient 
{
    public static void main(String[] args) throws UnknownHostException, IOException 
    {
        Socket s=new Socket("",6000);

        DataOutputStream dout=new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));

        byte[] a = {(byte)0xC0,(byte)0xA8,(byte)0x01,(byte)0x02,(byte)0x53,(byte)0x4D,(byte)0x41,(byte)0x52,(byte)0x54};
        dout.write(a);
        dout.close();
        s.close();
    }

}

Ответ 9

Ниже приведен пример, который передает по 100 байт файлов фреймов за один раз.

private Socket socket;

public void streamWav(byte[] myByteArray, int start, int len) throws IOException {

    Path path = Paths.get("path/to/file.wav");

    byte[] data = Files.readAllBytes(path);

    OutputStream out = socket.getOutputStream();
    DataOutputStream os = new DataOutputStream(out);

    os.writeInt(len);
    if (len > 0) {
        os.write(data, start, len);
    }
}

public void readWav() throws IOException {

    InputStream in = socket.getInputStream();

    int frameLength = 100; // use useful number of bytes

    int input;
    boolean active = true;

    while(active) {
        byte[] frame = new byte[frameLength];
        for(int i=0; i<frameLength; i++) {

            input = in.read();

            if(input < 0) {
                active = false;
                break;
            } else frame[i] = (byte) input;
        }

        // playWavPiece(frame);
        // streamed frame byte array is full
        // use it here ;-)
    }
}