2010-05-21 20 views
24

¿Alguien puede demostrar cómo enviar una matriz de bytes a través de una conexión TCP desde un programa emisor a un programa receptor en Java?cómo enviar una matriz de bytes a través de una conexión TCP (programación java)

byte[] myByteArray 

(soy nuevo en programación Java, y parece que no puede encontrar un ejemplo de cómo hacer esto muestra que ambos extremos de la conexión (emisor y receptor). Si usted sabe de un ejemplo existente , tal vez usted puede publicar el enlace. (No hay necesidad de reinventar la rueda.) PD: Esta es NO tarea! :-)

Respuesta

54

Las clases InputStream y OutputStream en Java manejan nativamente matrices de bytes. Lo único que querrá agregar es la longitud al comienzo del mensaje para que el receptor sepa cuántos bytes esperar. Normalmente me gusta ofrecer un método que permita controlar qué bytes de la matriz de bytes enviar, al igual que la API estándar.

Algo como esto:

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

EDITAR: Para añadir el lado receptor:

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

¿cómo puedo reproducir esto? como cuando se espera una corriente de entrada –

+0

@ChristopherFrancisco Loop? Simplemente llame a los métodos desde un bucle. Si quiere decir esperar un mensaje sin detener su programa, puede simplemente hacer la E/S en un hilo separado o modificar esto para usar NIO. –

+0

No lo he probado, pero si len> [TCP packet size], creo que readFully() podría no leer todos los contenidos, pero solo las primeras partes disponibles .... (https://docs.oracle.com/javase/ 7/docs/api/java/io/DataInput.html # readFully (byte [])) Por lo que este código podría no funcionar como en este caso, ¿verdad? – ntg

2

The Oracle Socket Communications Tutorial parece ser el punto de lanzamiento apropiado.

Tenga en cuenta que va a problema adicional para convertir caracteres en bytes. Si quieres trabajar en el nivel de bytes, solo quítalo.

+1

gracias, pero no muestra cómo enviar una matriz de bytes –

+0

¿No puede resolver el resto por su cuenta? –

1

Este Sun Sockets tutorial debería darle un buen punto de partida

+0

no muestra cómo enviar una matriz de bytes a través de –

+0

Luego necesita aprender sobre [IO básico] (http://java.sun.com/docs/books/tutorial/essential/io/) o para mirar respuesta de Kevin Brock :) – BalusC

4

Simplemente comienza con this example del Really Big Index. Sin embargo, tenga en cuenta que está diseñado para transmitir y recibir caracteres, no bytes. Sin embargo, esto no es un gran problema, solo puede tratar con los objetos InputStream y OutputStream sin procesar que ofrece la clase Socket. Consulte la API para obtener más información sobre los diferentes tipos de lectores, escritores y transmisiones. Los métodos que le interesarán son OutputStream.write(byte[]) y InputStream.read(byte[]).

1

Lo que hay que utilizar es el método write de un java.io.OutputStream, y el método de una java.io.InputStreamread, ambos de los cuales se puede recuperar de la Socket abrir.

0

supongo que la pregunta es por escrito incorrectamente. Encontré esto al buscar una respuesta de por qué mi uso de InputStream y OutputStream parecía estar configurando toda la matriz a 0 al encontrar un byte de valor 0. Suponiendo que los bytes contengan ASCII válido y no binario. Dado que la pregunta no surge y pregunta esto, y nadie más parece haberlo considerado posible, creo que tendré que satisfacer mi búsqueda en otro lado.

Lo que intentaba hacer era escribir una clase TransparentSocket que pudiera instanciar un TCP (Socket/ServerSocket) o un UDP (DatagramSocket) para usar el DatagramPacket de forma transparente. Funciona para UDP, pero no (todavía) para TCP.

Seguimiento: parece que he verificado que estas transmisiones son en sí mismas inútiles para las transferencias binarias, pero que se pueden pasar a una creación de instancias más amigable con los programadores, p.,

new DataOutputStream (socket.getOutputStream()). WriteInt (5);

^Mucho de esa idea. Escribe datos de forma "portátil", es decir, probablemente ASCII, lo que no ayuda en nada, ¡especialmente cuando emulo un software sobre el que no tengo control!

1

Le pediría que use ObjectOutputStream y ObjectInputStream. Estos envían todo como un objeto y reciben lo mismo.

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

Asimismo, recuerda en primer lugar crear el flujo de salida, tirar de la cadena y luego seguir adelante con el flujo de entrada porque si algo dejó fuera en la corriente del flujo de entrada suele ser creado.

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

¿Por qué debería el OP "probar esto"? Una ** buena respuesta ** siempre tendrá una explicación de lo que se hizo y por qué se hizo de esa manera, no solo para el OP sino para los futuros visitantes de SO que puedan encontrar esta pregunta y leer su respuesta. –

0

Aquí hay un ejemplo que transmite fotogramas de archivos wav de 100 bytes a la vez.

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