2010-05-30 15 views
17

Tengo una aplicación cliente servidor que se comunican usando objetos.
cuando envío solo un objeto desde el cliente al servidor, todo funciona bien.
cuando intento enviar varios objetos uno tras otro en la misma corriente me salejava.io.StreamCorruptedException: inválido cabecera de flujo: 7371007E

StreamCorruptedException. 

Puede alguien dirigir a la causa de este error?

método de cliente de escritura

private SecMessage[] send(SecMessage[] msgs) 
    { 
    SecMessage result[]=new SecMessage[msgs.length]; 
     Socket s=null; 
     ObjectOutputStream objOut =null; 
     ObjectInputStream objIn=null; 
     try 
     { 
     s=new Socket("localhost",12345); 
     objOut=new ObjectOutputStream(s.getOutputStream()); 
     for (SecMessage msg : msgs) 
     { 
      objOut.writeObject(msg); 
     } 
     objOut.flush(); 
     objIn=new ObjectInputStream(s.getInputStream()); 
     for (int i=0;i<result.length;i++) 
      result[i]=(SecMessage)objIn.readObject(); 
     } 
     catch(java.io.IOException e) 
     { 
     alert(IO_ERROR_MSG+"\n"+e.getMessage()); 
     } 
     catch (ClassNotFoundException e) 
     { 
     alert(INTERNAL_ERROR+"\n"+e.getMessage()); 
     } 
     finally 
     { 
     try {objIn.close();} catch (IOException e) {} 
     try {objOut.close();} catch (IOException e) {} 
     } 
     return result; 
} 

método de lectura del servidor

//in is an inputStream Defined in the server 
SecMessage rcvdMsgObj; 
rcvdMsgObj=(SecMessage)new ObjectInputStream(in).readObject(); 
return rcvdMsgObj; 

y de la Clase SecMessage es

public class SecMessage implements java.io.Serializable 
{ 
private static final long serialVersionUID = 3940341617988134707L; 
private String cmd; 
    //... nothing interesting here , just a bunch of fields , getter and setters 
} 
+0

he formateado un poco para facilitar la lectura - puede dar formato a los bloques de código utilizando el botón (101 010). – mdma

Respuesta

7

Si va a enviar varios objetos, a menudo es más simple ponerlos en algún tipo de titular/colección como Object[] o List. Le ahorra tener que comprobar explícitamente el final del flujo y se encarga de transmitir explícitamente cuántos objetos hay en el flujo.

EDIT: Ahora que he formateado el código, veo que ya tiene los mensajes en una matriz. Simplemente escriba la matriz en la secuencia de objetos y lea la matriz en el lado del servidor.

Su "método de lectura del servidor" solamente es la lectura de un objeto. Si se llama varias veces, recibirá un error ya que está tratando de abrir varias secuencias de objetos desde la misma secuencia de entrada. Esto no funcionará, ya que todos los objetos se escribieron en el mismo flujo de objetos en el lado del cliente, por lo que debe reflejar esta disposición en el lado del servidor. Es decir, use una secuencia de entrada de objeto y lea múltiples objetos a partir de eso.

(El error que obtienes es porque objectOutputStream escribe un encabezado, que es esperado por objectIutputStream. Como no estás escribiendo varias secuencias, sino simplemente varios objetos, el siguiente objectInputStream creado en la entrada del socket no puede encontrar un segundo cabecera, y produce una excepción.)

solucionarlo, cree el ObjectInputStream cuando se acepta la conexión de socket. Pase this objectInputStream al método de lectura del servidor y lea Object from that.

+0

Me di cuenta de eso. Solo quería evitarlo ya que esto requerirá que cambie diferentes partes del código. Esto es lo que haré eventualmente, solo quería saber cuál podría ser mi problema. gracias! , esto me estaba volviendo loco. – Alex

1

cuando envío un solo objeto desde el cliente al servidor de todos funciona bien.

cuando intento enviar varios objetos uno tras otro en la misma corriente consigo StreamCorruptedException.

En realidad, su código de cliente está escribiendo un objeto al servidor y lectura múltiples objetos desde el servidor. Y no hay nada en el lado del servidor que sea escribiendo los objetos que el cliente está tratando de leer.

+0

el cliente está escribiendo varios objetos para (mensaje SecMessage: msgs) { ObjOut.writeObject (msg); } el servidor se encarga de enviar una respuesta para cada solicitud yo no he incluido el código aquí porque no quiero saturar el puesto, y no parece la escritura lado a otro servidor al cliente para causar cualquier problema, disculpa por la respuesta desordenada, no sé cómo formatear el comentario correctamente. – Alex

-2

Esta excepción también puede ocurrir si usa Socket s en un lado y SSLSocket s en el otro. La consistencia es importante.

+0

incorrecto Si lo hace, no obtendrá el último apretón de manos SSL. – EJP