Android: Socket - java.net.SocketException: ошибка отправки: EPIPE (сломанный канал)

Я пытаюсь установить соединение с сервером, используя сокет. Соединительная труба сломана, как показано ниже. Исключения.

01-31 14:47:16.536: W/System.err(27255): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
01-31 14:47:16.550: W/System.err(27255):    at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:496)
01-31 14:47:16.550: W/System.err(27255):    at libcore.io.IoBridge.sendto(IoBridge.java:465)
01-31 14:47:16.550: W/System.err(27255):    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
01-31 14:47:16.550: W/System.err(27255):    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
01-31 14:47:16.664: W/NetworkManagementSocketTagger(24437): setKernelCountSet(10021, 1) failed with errno -2
01-31 14:47:16.684: W/System.err(27255):    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269)
01-31 14:47:16.693: W/System.err(27255):    at java.io.DataOutputStream.write(DataOutputStream.java:98)
01-31 14:47:16.693: W/System.err(27255):    at java.io.OutputStream.write(OutputStream.java:82)
01-31 14:47:16.693: W/System.err(27255):    at com.x.x.y.sendRec(y.java:460)
01-31 14:47:16.693: W/System.err(27255):    at com.x.x.y.access$0(y.java:384)
01-31 14:47:16.693: W/System.err(27255):    at com.x.x.y$2.run(y.java:363)
01-31 14:47:16.693: W/System.err(27255):    at java.lang.Thread.run(Thread.java:856)
01-31 14:47:16.693: W/System.err(27255): Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
01-31 14:47:16.693: W/System.err(27255):    at libcore.io.Posix.sendtoBytes(Native Method)
01-31 14:47:16.693: W/System.err(27255):    at libcore.io.Posix.sendto(Posix.java:146)
01-31 14:47:16.693: W/System.err(27255):    at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
01-31 14:47:16.693: W/System.err(27255):    at libcore.io.IoBridge.sendto(IoBridge.java:463)

Вот код и в этой строке outStreamRec.write(bData); выбрасывается исключение.

    try {
        port = 86;
        byterecv = new byte[1040];
        clientRec = new Socket();
        clientRec.connect(new InetSocketAddress("192.168.1.36", port));
        System.out.println("Just connected to " + clientRec.getRemoteSocketAddress());
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }
    while (true) {
        try {
            System.out.println("Connecting to " + ServerUrl.url + " on port " + port);              
            OutputStream outToServerRec = clientRec.getOutputStream();
            DataOutputStream outStreamRec = new DataOutputStream(outToServerRec);

            outStreamRec.write(bData);

            InputStream inFromServerPlay = clientRec.getInputStream();
            DataInputStream inStreamPlay = new DataInputStream(inFromServerPlay);
            while ((lstream = inStreamPlay.read(byterecv)) != -1) {
                System.out.println("startrec bytearray -- " + byterecv.length);
                bos1.write(byterecv, 0, lstream);
            }                
            if (stopcall == true) {
                clientRec.close();
                break;
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Примечание: если я закрываю соединение с сокетом, немедленно работает нормально. Но я хочу сохранить соединение, но я закрываю соединение сокета вручную. При нажатии кнопки «Стоп» я закрываю соединение.

Я искал в Интернете, но не нашел способа исправить это.


person Rahul Baradia    schedule 31.01.2013    source источник
comment
Это в основном (UI) потоке?   -  person keyser    schedule 31.01.2013
comment
нет .. это не в основном потоке пользовательского интерфейса   -  person Rahul Baradia    schedule 31.01.2013


Ответы (4)


Одноранговый узел закрыл соединение, пока вы писали ему. Обычно это означает, что вы отправили ему что-то, чего он не понял. Возможно, это HTTP-сервер? Или какой-то другой протокол, который вы не реализовали в своем клиентском коде?

person user207421    schedule 31.01.2013
comment
Но что я могу сделать, чтобы исправить это? Вот это важный вопрос. - person Sreekanth Karumanaghat; 29.08.2013
comment
@SreekanthKarumanaghat Не записывайте в соединение после того, как одноранговый узел закрыл его! Это указывает на ошибку протокола приложения с вашей стороны. Либо одноранговый узел закрылся, когда этого не должно было быть, либо вы отправляете сообщение, когда не должны. - person user207421; 01.09.2013
comment
Говоря, что peer закрыл соединение... вы имеете в виду, что сервер закрыл соединение...? - person Eido95; 22.06.2017
comment
@ Eido95 Нет, я этого не делал. Я имел в виду то, что сказал. Я имею в виду ровесника. Как только TCP-соединение установлено, бессмысленно думать о сервере и клиенте. Они оба ровесники друг друга. Если говорить о сервере, если этот конец является клиентом, или о клиенте, если этот конец является сервером, объем ответа увеличился бы только втрое. Это не имеет ни малейшего значения. Важно то, что закрылся пир, а не локальный конец. - person user207421; 22.06.2017

Мои два цента: у нас была такая же проблема (BROKEN EPIPE), и, просматривая Fiddler (или Charls, или WireShark, или другой прокси-отладчик/прослушиватель/и т. д.), мы заметили, что запрос вообще не отправляется.

Причина в том, что мы добавили заголовок «Content-Length» с неверным значением.

person Felix    schedule 16.04.2015
comment
Вы, вероятно, не должны были добавлять его вообще. Вероятно, библиотека сделает это за вас. HttpURLConnection определенно делает. - person user207421; 01.04.2016
comment
Я сверился с разработчиком, который это написал, и он сказал, что, если он правильно помнит, проблема в том, что заголовок не добавляется при использовании setChunkedStreamingMode(x) (потому что это запрещено, см. Wikipedia), но привязка MS-WCF, используемая сервером, требует этого, даже если включена функция Chunked Streaming. - person Felix; 03.04.2016
comment
Тогда это ошибка в MS-WCF. - person user207421; 07.02.2017

Я столкнулся с такой проблемой на планшете Samsung (GT-P5113, Android 4.2.2), приложение хорошо работает на других устройствах (Nexus 4/5/7).

Код в Libcore/io/IoBridge.java выглядит так:

public static int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws IOException {
    boolean isDatagram = (inetAddress != null);
    if (!isDatagram && byteCount <= 0) {
        return 0;
    }
    int result;
    try {
        result = Libcore.os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port);
    } catch (ErrnoException errnoException) {
        result = maybeThrowAfterSendto(isDatagram, errnoException);
    }
    return result;
}

в то время как Libcore.os.sendto() является собственным вызовом.

Возможно, попробуйте еще раз, это хороший кандидат на обходной путь.

person Zephyr    schedule 07.10.2015
comment
Это не так. Это ошибка протокола приложения. Код приложения не изменится между повторными попытками. - person user207421; 01.04.2016

У меня тоже было, и глупая причина заключалась в том, что интернет на устройстве не работал должным образом.

Проверьте подключение к Интернету, это может быть причиной.

person Danger    schedule 10.07.2017
comment
хотя технически он прав. Кто бы ни проголосовал за это, в какой-то момент наверняка совершит подобную глупую ошибку. - person CiriousJoker; 19.04.2020