简体   繁体   中英

Keep TCP socket-connection alive if no data is currently available

I have implemented a small HTTP-server which allows clients to connect via HTTP and stream audio-data to them.

My problem is, that in case there's currently no audio-data available, the connection seems to break, either because the client is disconnecting, or due to another reason inside Android.

I'm acting like the following way:

serverSocket = new ServerSocket(0);
Socket socket = serverSocket.accept();
socket.setKeepAlive(true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

out.write("HTTP/1.1 200 OK\r\n");
out.write("Content-Type: audio/wav\r\n");
out.write("Accept-Ranges: none\r\n");
out.write("Connection: keep-alive\r\n"); // additionally added due to answer below
out.write("\r\n");
out.flush();
..
while(len=otherInput.read(audioBuffer)){
 out.write(audioBuffer, 0, len);)
}

For sure this is just a snipped of the real code, but it shows what I'm doing. Now, in case the "otherinput.read()" takes a long time because there's no data available at the moment, I get a

java.net.SocketException: sendto failed: EPIPE (Broken pipe)
    at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:499)
    at libcore.io.IoBridge.sendto(IoBridge.java:468)
    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508)
    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270)
    at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
    at java.io.BufferedOutputStream.write(BufferedOutputStream.java:139)

Who can tell me how I can prevent the connection from breaking/closing without a manual heartbeat? Do I miss some header or am I using something the wrong way?

Thanks for your help in advance, tried and searched myself crazy meanwhile.

There are at least two problems here.

  1. Clients of HTTP servers are not well-behaved in the way you seem to expect. Consider a browser. The user can shut it down, go back, navigate away etc, any time he likes, even in the middle of a page load. If you get any error transmitting to the client there's nothing you can do except close the connection and forget about it. Same applies to any server really, but it applies unsolder to HTTP servers.

  2. You're not reading the entire request sent by the client. You need to read all the headers until a blank line, then you need to read the body up to the length specified in the Content-length: header, or all the chunks, or until end of stream, as the case may be: see RFC 2616. The effect of this may be that you cause the behaviour at (1).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM