2014-04-29 17 views
6

Sto cercando di leggere i dati da socket server dal client in Android.java.net.SocketException: sendto fallita: EPIPE (tubo rotto) su Android

Ecco i frammenti di codice che sto usando:

client (Su Android in JAVA)

DataOutputStream dataOutputStream = null; 
    DataInputStream dataInputStream = null; 
    try { 

     if (client.socket == null || !client.socket.isConnected()) 
      client.createSocket(); 

     // Get Input/Output stream for socket 
     dataOutputStream = new DataOutputStream(client.socket.getOutputStream()); 
     dataInputStream = new DataInputStream(client.socket.getInputStream()); 

     // Here RS is simple JAVA class that stores information about payload and response length 
     Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len()); 

     dataOutputStream.write(UtilsManager.serialize(RS.getPayload())); 

     // Notify waiting Queue thread to start processing next packet 
     if (RS.getResponse_len() > 0) { 
      Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes"); 

      int totalRead = 0; 

      byte[] buffer = new byte[RS.getResponse_len()]; 
      while (totalRead < RS.getResponse_len()) { 
       int bytesRead = dataInputStream.read(buffer, totalRead, RS.getResponse_len() - totalRead); 

       if (bytesRead < 0) { 
        throw new IOException("Data stream ended prematurely"); 
       } 
       totalRead += bytesRead; 
      } 
    } 

Server (Python)

 # Here request_len is the expected request size 
     while buffer_len < response_set.request_len: 
      new_data = connection.recv(min(self.buff_size, response_set.request_len-buffer_len)) 
      if not new_data: 
       return False 
      buffer_len += len(new_data) 

     # Send required response 
     for response in response_set.response_list: 
      try: 
       connection.sendall(str(response.payload)) 
      except: 
       return False 

volte , Sto ricevendo un errore mentre sto inviando il payload dal client on line

 dataOutputStream.write(UtilsManager.serialize(RS.getPayload())); 

errore sto ottenendo è:

java.net.SocketException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506) 
    at libcore.io.IoBridge.sendto(IoBridge.java:475) 
    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507) 
    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46) 
    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269) 
    at java.io.DataOutputStream.write(DataOutputStream.java:98) 
    at java.io.OutputStream.write(OutputStream.java:82) 
    at com.rgolani.replay.tcp.TCPClientThread.run(TCPClientThread.java:56) 
    at java.lang.Thread.run(Thread.java:856) 
Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.Posix.sendtoBytes(Native Method) 
    at libcore.io.Posix.sendto(Posix.java:151) 
    at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177) 
    at libcore.io.IoBridge.sendto(IoBridge.java:473) 
    ... 7 more 

So che questo è po 'di confusione. Il codice Python non è stato scritto da me e esiste un client python che funziona senza errori. Sto ricevendo questo errore solo nel mio codice JAVA.

di lavoro Python client

if self.sock is None: 
     self._connect_socket() 

    self.sock.sendall(tcp.payload) 

    buffer_len = 0 
    while tcp.response_len > buffer_len: 
     data = self.sock.recv(min(self.buff_size, tcp.response_len-buffer_len)) 
     buffer_len += len(data) 

Per favore fatemi sapere se avete bisogno di ulteriori informazioni.

Grazie.

risposta

0

Forse mi manca un punto con il tuo problema, ma penso che sarebbe meglio utilizzare questo frammento Java:

import java.io.ObjectOutputStream; 
import java.io.ObjectInputStream; 

ObjectOutputStream dataOutputStream = null; 
ObjectInputStream dataInputStream = null; 
try { 

    if (client.socket == null || !client.socket.isConnected()) 
     client.createSocket(); 

    // Get Input/Output stream for socket 
    dataOutputStream = new ObjectOutputStream (client.socket.getOutputStream()); 
    dataInputStream = new ObjectInputStream (client.socket.getInputStream()); 

    // Here RS is simple JAVA class that stores information about payload and response length 
    Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len()); 

    // You might consider using java.io.Serializable interface with the argument object 
    dataOutputStream.writeObject(UtilsManager.serialize(RS.getPayload())); 

    // Notify waiting Queue thread to start processing next packet 
    if (RS.getResponse_len() > 0) { 
     Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes"); 

     // Read a java.io.Serializable object from the stream. So you have to write a java.io.Serializable object into the stream. 
     Object o = dataInputStream.readObject(); 
    } 
} 

Spero che questo aiuti ...

1

Se si utilizza setChunkedStreamingMode poi rimuovilo e poi guarda. Penso di essere così in ritardo, ma questo risolve il mio problema. Puoi usare la modalità di streaming a lunghezza fissa.

+0

Uso 'setChunkedStreamingMode' a causa di [collegamento] (http://stackoverflow.com/questions/9630430/upload-large-file-in-android-without-outofmemory-error). E incontralo una volta. Il php di sever non consente una lunghezza non fissa. Dovrebbe essere risolto sul lato server e non è necessario rimuovere il codice sul client. – Yeung

1

Questo errore si verifica quando il client tenta di scrivere una connessione quando il backend ha già chiuso esso. Per impostazione predefinita, Android imposta la proprietà Keep Alive su true e riutilizzerà le vecchie connessioni socket poiché stabilire una connessione è un'operazione che consuma risorse in un ambiente mobile (è possibile testarlo con uno strumento come fiddler). Prova a impostare l'intestazione Connection a close o chiamare System.setProperty("http.keepAlive", "false"); per disabilitare mantenere viva e costringendo così il sistema per creare una nuova connessione.

0

Nel mio caso: client.createSocket(); non connettersi a nessun server: basta creare un socket. Quindi più tardi devo client.connect (_sock_sddr_here_);

isconnected anche() - prova di stupido perché è sempre vero.

Problemi correlati