There is a big group of today, send a link to http://93.175.29.89:8008/, said climb the url, IO will always stuck in that, there has been no response back. The URL is a special request he constructed. It outputs a video stream, but the server does not return Content-Length, nor does it output real data. It outputs a stream of less than 1024 bytes and then stays there without closing.

ReadTimeout is not a big problem. He said he had set readTimeout, but it didn’t work. At first, I thought it was his code, or the API library implementation problem

package sms.bai.util; import com.squareup.okhttp.Headers; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; import java.io.IOException; import java.util.concurrent.*; public class Req { public static void reqUrl() throws IOException { OkHttpClient client = new OkHttpClient(); client.setConnectTimeout(5,TimeUnit.SECONDS); client.setReadTimeout(5,TimeUnit.SECONDS); Request the Request = new Request. The Builder (). The url (" http://93.175.29.89:8008/ "). The build (); Response response = client.newCall(request).execute(); if (! Response.isSuccessful ()) {throw new IoException (" Server error: "+ response.isSuccessful); } Headers responseHeaders = response.headers(); for (int i = 0; i < responseHeaders.size(); i++) { System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); } System.out.println(response.body().string()); } public static void main(String[] args) throws IOException { reqUrl(); }}

Sure enough, neither setting ConnectTimeout nor ReadTimeout works. The code stays in the output and does not print any body (you can barely see the screen in the browser), and the program does not stop

Content-Type: multipart/x-mixed-replace; boundary=---nessy2jpegboundary OkHttp-Sent-Millis: 1582028133591 OkHttp-Received-Millis: 1582028133875

You’re using the OkHttp library here, but you could use another library or use Java’s native HttpURLConnection to theoretically have the same effect.

Look at the request in FFMPEG

[kk @ kk ~] $ffmpeg -i http://93.175.29.89:8008/ - f mp4 out. Mp4 ffmpeg version n4.2.2 Copyright (c) 2000-2019 the ffmpeg Developers built with GCC 9.2.0 (GCC) libavutil 56.31.100/56.31.100 libavcodec 58.54.100/58.54.100 libavformat 58. 29.100/58. 29.100 libavDevice 58. 8.100/58. 8.100 libavFilter 7.57.100/7.57.100 libswscale 5.5.100/5. 5.100 libswresample 3.5.100/3.5.100 libpostproc 55.5.100/55.5.100 Input #0, mpjpeg, mpjpeg The from 'http://93.175.29.89:8008/' : Duration: N/A, bitrate: N/A Stream # 0-0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 640x480 [SAR 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc Stream mapping: Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264)) Press [q] to stop, [?]  for help [libx264 @ 0x562ad6812cc0] using SAR=1/1 [libx264 @ 0x562ad6812cc0] using cpu capabilities: MMX2 SSE2FAST SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2 [LIBX264@0x562AD6812CC0] PROFILE HIGH, LEVEL 3.0, 4:2:0, 8-bit [libx264 @ 0x562ad6812cc0] 264 - core 159 r2991 1771b55 - H.264/MPEG-4 AVC codec - Copyleft 2003-2019 - http://www.videolan.org/x264.html - options: Cabac = 1 ref = 3 deblock = 1:0:0 analyse x3 = 0:0 x113 me = hex subme = 7 psy = 1 psy_rd = 1.00:0.00 mixed_ref = 1 me_range = 16 chroma_me = 1 Trellis =1 8x8dct=1 Cqm =0 Deadzone =21,11 FAST_PSKIP =1 Chroma_Qp_Offset =-2 threads=12 Lookahead_Threads =2 Slyed_Threads =0  nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 CRF = 23.0qcomp =0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 Output #0, mp4, to 'out.mp4': Metadata: encoder: Lavf58.29.100 Stream 0-0 at # : Video: h264 (libx264) (avc1 / 0x31637661), yuvj420p(pc), 640x480 [SAR 1:1 DAR 4:3], q=-1--1, 25 fps, 12800 tbn, 25 TBC Metadata: encoder: Lavc58.54.100 libx264 Side data: CPB: bitrate Max /min/avg: 0/0/0 buffer size: 0 vbv_delay: -1 frame= 8fps = 1.1q = -1.0lsize = 336kB time=00:00:03.20. -1 frame= 8fps = 1.1q = -1.0lsize = 336kB time=00:00:03.20

FFmpeg recognizes that it is a video stream, but it stays stuck at frame=xx and keeps reading frames without stopping. Forced termination can output a few seconds long video

The solution

The SocketTimeoutException in HttpURLConnection does not have a solution to the SocketTimeoutException. Change the main method to the following

public static void main(String[] args) throws Exception { final ExecutorService exec = Executors.newFixedThreadPool(1); Call = new Callable<String>() {public String call() throws Exception {reqUrl(); Return "Thread execution complete."; }}; Future<String> future = null; try { future = exec.submit(call); String obj = future.get(1000 * 10, TimeUnit.MILLISECONDS); System.out.println(" Task returned successfully :" + obj); } catch (TimeoutException ex) {System.out.println(" timeout....") {System.out.println(); ); ex.printStackTrace(); future.cancel(true); } catch (Exception E) {System.out.println(" Error ");} catch (Exception E) {System.out.println(" Error. e.printStackTrace(); }finally {// Close the thread pool System.out.println(" Close the thread pool "); exec.shutdown(); }}

So now we have the desired result

Content-Type: multipart/x-mixed-replace; Boundary =-- nessy2jpegboundary okhttp-sent-millis: 1582028854911 okhttp-Received -Millis: 1582028855178 processing timeout.... java.util.concurrent.TimeoutException at java.util.concurrent.FutureTask.get(FutureTask.java:205) at Main (req.java :47) Finished with exit code 0

So what does the timeout in HttpURLConnection mean? Why doesn’t it work? Take a look at the documentation. ConnectTimeout: ConnectTimeout

Sets a specified timeout value, in milliseconds, to be used when opening a communications link to the resource referenced by this URLConnection. If the timeout expires before the connection can be established, a java.net.SocketTimeoutException is raised. A timeout of zero is interpreted as an infinite timeout.

Some non-standard implmentation of this method may ignore the specified timeout. To see the connect timeout set, please call getConnectTimeout().

It means the time it takes to make a connection. If no connection has been established by the specified time, an exception is reported. This is a little bit easier to understand.

ReadTimeout, Java explains it like this:

Sets the read timeout to a specified timeout, in milliseconds. A non-zero value specifies the timeout when reading from Input stream when a connection is established to a resource. If the timeout expires before there is data available for read, a java.net.SocketTimeoutException is raised. A timeout of zero is interpreted as an infinite timeout.

Some non-standard implementation of this method ignores the specified timeout. To see the read timeout set, please call getReadTimeout().

A connection has been established and the server resource is being read. If no possible data is read by the client by the specified time, an exception is raised.

SetReadTimeout not mean read complete, it mean when wait for 10s, when there’s no more data read in, Will throw a TimeoutException.

So for this particular server configuration, there is no SocketTimeoutException to resolve the timeout, but only a layer on the outside that is controlled by the thread timeout.

By the way, Python does this by setting a gevent timeout, and the principle is the same.


Expansion and Thinking

Callable and Feature are originally concepts of thread pools in Java, but they are used to solve timeouts and are even necessary tools in some scenarios. What are some other great uses of thread pools?

What other scenarios do you need to use Callable and Feature?

For some imperfect connection libraries, where there is no mechanism to provide ConnectTimeout and ReadTimeout, we can use the timeout mechanism of the thread pool. For example, when I use the official native Java Client of HDFS, its connection method parameter does not have a timeout setting, so if the HDFS service fails, the client can only wait. In this case, it is necessary to implement a set of timeout mechanism.