socket - server tcp in java




come inviare una matrice di byte su una connessione TCP(programmazione java) (6)

Qualcuno può dimostrare come inviare una matrice di byte su una connessione TCP da un programma mittente a un programma ricevente in Java.

byte[] myByteArray

(Sono nuovo nella programmazione Java e non riesco a trovare un esempio di come fare ciò che mostra entrambe le estremità della connessione (mittente e destinatario). Se conosci un esempio esistente, potresti pubblicare il link . (Non c'è bisogno di reinventare la ruota.) PS Questo NON è compito! :-)


Ecco un esempio che esegue lo streaming di frame di 100 byte wav alla volta.

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 ;-)
    }
}

Immagino che la domanda sia formulata in modo errato. Ho trovato questo quando cercavo una risposta al motivo per cui il mio uso di InputStream e OutputStream sembrava impostare l'intero array su 0 incontrando un byte di valore 0. Si assume che i byte contengano ASCII valido e non binario. Dal momento che la domanda non arriva e chiede questo, e nessuno sembra averlo preso come una possibilità, credo che dovrò soddisfare la mia ricerca altrove.

Quello che stavo cercando di fare era scrivere una classe TransparentSocket in grado di istanziare un TCP (Socket / ServerSocket) o un UDP (DatagramSocket) per usare il DatagramPacket in modo trasparente. Funziona per UDP, ma non (ancora) per TCP.

Follow-up: mi sembra di aver verificato che questi flussi sono essi stessi inutili per i trasferimenti binari, ma che possono essere passati a un'istanza più programmabile, ad es.

nuovo DataOutputStream (socket.getOutputStream ()). writeInt (5);

^ Così tanto per quell'idea. Scrive i dati in un modo "portatile", vale a dire, probabilmente ASCII, che non aiuta affatto, soprattutto quando si emula software su cui non ho controllo!


Le classi InputStream e OutputStream in Java gestiscono in modo nativo le matrici di byte. L'unica cosa che potresti voler aggiungere è la lunghezza all'inizio del messaggio in modo che il destinatario sappia quanti byte aspettarsi. In genere mi piace offrire un metodo che consente di controllare quali byte nella matrice di byte inviare, in modo molto simile all'API standard.

Qualcosa come questo:

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 : per aggiungere il lato ricevente:

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;
}

Quello che devi usare è il metodo di write di un java.io.OutputStream e il metodo di read di un java.io.InputStream , entrambi i quali puoi recuperare dal Socket aperto.


Ti chiederei di utilizzare ObjectOutputStream e ObjectInputStream. Questi inviano tutto come un oggetto e ricevono lo stesso.

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();

Ricorda anche di creare prima il flusso di output, svuotarlo e poi andare avanti con il flusso di input, perché se qualcosa lasciato fuori nel flusso non verrà creato il flusso di input.


Il tutorial Oracle Socket Communications sembrerebbe essere il punto di lancio appropriato.

Tieni presente che si verificheranno ulteriori problemi per trasformare i caratteri in byte. Se vuoi lavorare a livello di byte, basta staccarlo.







bytearray