Android: Socket - java.net.SocketException: sendto неуспешно: 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
Като казвате партньорът затвори връзката... имате предвид, че сървърът затвори връзката...? - 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