2010-05-21 29 views
24

Qualcuno può dimostrare come inviare una matrice di byte su una connessione TCP da un programma mittente a un programma ricevitore in Java.come inviare una matrice di byte su una connessione TCP (programmazione java)

byte[] myByteArray 

(Sono nuovo di programmazione Java, e non riesco a trovare un esempio di come fare questo che mostra entrambe le estremità della connessione (mittente e destinatario.) Se siete a conoscenza di un esempio esistente , forse si potrebbe postare il link. (Non c'è bisogno di reinventare la ruota.) PS Questo è NON compiti! :-)

risposta

54

Le classi InputStream e OutputStream in Java gestiscono nativamente gli array 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 di simile a 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; 
} 
+0

come posso fare un loop? come quando aspetti un flusso di input –

+0

@ChristopherFrancisco Loop? Basta chiamare i metodi da un ciclo. Se si intende attendere un messaggio senza arrestare il programma, è sufficiente eseguire l'I/O su un thread separato o modificarlo per utilizzare NIO. –

+0

Non ho ancora testato, ma se len> [TCP dimensione del pacchetto], penso che readFully() potrebbe non leggere tutti i contenuti, ma solo i primi parti disponibili .... (https://docs.oracle.com/javase/ 7/docs/api/java/io/DataInput.html # readFully (byte [])) Quindi, questo codice potrebbe non funzionare come in questo caso, giusto? – ntg

2

The Oracle Socket Communications Tutorial sembrerebbe essere il punto di lancio appropriata.

Si noti che sta per problemi aggiuntivi per trasformare i caratteri in byte. Se vuoi lavorare a livello di byte, basta staccarlo.

+1

grazie, ma non mostra come inviare un array di byte –

+0

Non riesci a capire il resto te stesso? –

1

Questo Sun Sockets tutorial dovrebbe darvi un buon punto di partenza

+0

non mostra come inviare un array di byte se –

+0

allora avete bisogno di conoscere [base IO] (http://java.sun.com/docs/books/tutorial/essential/io/) o da guardare risposta di Kevin Brock :) – BalusC

4

Basta partire con this example dal Really Big Index. Si noti tuttavia che è progettato per trasmettere e ricevere caratteri, non byte. Questo non è un grosso problema, però: puoi gestire solo gli oggetti InputStream e OutputStream non elaborati forniti dalla classe Socket. Vedi l'API per maggiori informazioni sui diversi tipi di lettori, scrittori e stream. I metodi che ti interessano sono OutputStream.write(byte[]) e InputStream.read(byte[]).

1

Quello che è necessario utilizzare è il metodo write di un java.io.OutputStream, e il metodo di un java.io.InputStreamread, entrambi i quali è possibile recuperare dal Socket si apre.

0

Sto indovinando che la domanda è formulata in modo non corretto. 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 utilizzare 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ù adatta ai programmatori, ad es.,

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

^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!

1

vi chiedo di usare 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(); 

Ricordiamo anche prima creare il flusso di output, sciacquare e poi andare avanti con il flusso di input perché se qualcosa lasciato fuori nel flusso di flusso di input wont essere creato.

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

} 
+0

Perché l'OP dovrebbe "provare questo"? Una ** buona risposta ** avrà sempre una spiegazione di cosa è stato fatto e perché è stato fatto in quel modo, non solo per l'OP ma per i futuri visitatori di SO che potrebbero trovare questa domanda e leggere la tua risposta. –

0

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