java.net.SocketException: sendto failed: EPIPE (Broken pipe) on Android

Rajesh Golani picture Rajesh Golani · Apr 29, 2014 · Viewed 13k times · Source

I am trying to read data from server socket from client in Android.

Here are the snippets of code that I'm using:

Client (On 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

Sometimes, I am getting error while I'm sending payload from client on line

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

Error I'm getting is:

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

I know this is little bit confusing. Python code has not been written by me and there exists a python client which works without any errors. I'm getting this error only in my JAVA code.

Working 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)

Please let me know if you need more information.

Thank you.

Answer

Sumit Joshi picture Sumit Joshi · Dec 4, 2014

If you are using setChunkedStreamingMode then remove it and then see.I think I am so late but this solves my problem.You can use fixed length streaming mode.