建立 HTTP 请求超时 – Java

huangapple go评论63阅读模式
英文:

establish http request with Timed out - Java

问题

我正在寻找一种通过Java建立HTTP请求以确保服务器存活的方法。

例如,我想要扫描IP地址范围192.168.1.1-255并打印带有活动服务器的日志。

当由于某种原因HTTP响应延迟时,我想将超时设置为3秒。

我尝试过以下方式:

try {
    Socket s = new Socket(InetAddress.getByName("192.168.1.2"), 80);
    s.setSoTimeout(3 * 1000);
    PrintWriter pw = new PrintWriter(s.getOutputStream());
    pw.println("GET / HTTP/1.1");
    pw.println("Host: stackoverflow.com");
    pw.println("");
    pw.flush();
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    String t;
    while ((t = br.readLine()) != null) System.out.println(t);
    br.close();
} catch (SocketTimeoutException e) {
    System.out.println("服务器无响应。");
} catch (ConnectException e) {
    System.out.println("服务器无响应。");
}

但是当请求花费的时间超过3000毫秒时,似乎根本没有等待。

谢谢!

英文:

I'm looking for a way to establish an HTTP Request via java to ensure the server is alive.

for example I want to scan ip addresses range 192.168.1.1-255 and print a log with the living server.,

I want to setTimeOut for 3Seconds when the HTTP response is delayed for some reason.

I have tried to do it this way:

try {
            Socket s = new Socket(InetAddress.getByName("192.168.1.2"), 80);
            s.setSoTimeout(3 * 1000);
            PrintWriter pw = new PrintWriter(s.getOutputStream());
            pw.println("GET / HTTP/1.1");
            pw.println("Host: stackoverflow.com");
            pw.println("");
            pw.flush();
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String t;
            while ((t = br.readLine()) != null) System.out.println(t);
            br.close();
        } catch (SocketTimeoutException e) {
            System.out.println("Server is dead.");
        } catch (ConnectException e) {
            System.out.println("Server is dead.");
        }

But it's seem to be not waiting at all when the request is taking longer than 3000millis.

Thanks!

答案1

得分: 1

以下是翻译好的部分:

我认为你混淆了不同的超时时间。如果你想在三秒内没有任何响应的情况下中止连接尝试,那么你应该按照以下方式建立连接:

Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);

其中 target 是任何 IP 地址。以下这行代码实际上设置了读取/等待输入流的超时值 - 在连接建立之后。所以它对建立连接本身没有影响。然而,在连接建立后,它会在三秒后中断 "读取输入流" 步骤(通过抛出异常)。

clientSocket.setSoTimeout(3 * 1000);

但是,如果你还想限制从输入流中读取数据的时间,而不抛出异常,那么你需要一个自定义的解决方案:
https://stackoverflow.com/questions/804951/is-it-possible-to-read-from-a-inputstream-with-a-timeout

以下是一个在我的本地网络中非常好用的运行示例。它尝试在最多三秒内建立连接,并检测所有正在运行的 Web 服务器。

public class Main {
    public static void main(String[] args) {
        String net = "192.168.168."; // 这是我的本地网络
        for (int i = 1; i < 255; i++) { // 我们扫描范围 1-255
            String target = net + i;
            System.out.println("尝试连接到:" + target);
            try {
                Socket clientSocket = new Socket();

                // 我们尝试建立连接,超时时间为三秒
                clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);

                // 与服务器通信
                PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
                out.println("GET / HTTP/1.1");
                out.println("Host: stackoverflow.com");
                out.println("");
                out.flush();
                BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                String t;
                while ((t = br.readLine()) != null) System.out.println(t); // 打印服务器的响应
                br.close();
                clientSocket.close();

                // 服务器似乎是活动的
                System.out.println("> 服务器是活动的");
            } catch (SocketTimeoutException | ConnectException e) {
                System.out.println("> 服务器已关闭");
            } catch (Exception e) { // 这不是很好,但这只是一个演示
                e.printStackTrace();
            }
        }
    }
}

输出(摘录):

尝试连接到:192.168.168.1
> 服务器已关闭
尝试连接到:192.168.168.2
> 服务器已关闭
...
尝试连接到:192.168.168.23
(服务器的响应)
> 服务器是活动的

注意:代码段中的部分 HTML 实体在翻译中可能无法被准确表示。

英文:

I think you confused the different timeouts. If you want to abort the connection attempt after three seconds without any response, then you should establish the connection as follows:

Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);

where target is any IP address. The following line essentially set the timeout value for reading/waiting for the inputstream -after the connection was established. So it has not effect on establishing the connection itself. However, after the connection was established it would interrupt the "read inputstream" step after three seconds (by throwing an exception).

clientSocket.setSoTimeout(3 * 1000);

However, if you want to limit also the time for reading the inputstream without throwing an exception, then you need a costum solution:
https://stackoverflow.com/questions/804951/is-it-possible-to-read-from-a-inputstream-with-a-timeout

The following running example worked very well in my local network. It tried to connect for at most three seconds and detected all running webservers.

public class Main {
public static void main(String[] args) {
String net = &quot;192.168.168.&quot;; // this is my local network
for (int i = 1; i &lt; 255; i++) { // we scan the range 1-255
String target = net + i;
System.out.println(&quot;Try to connect to: &quot; + target);
try {
Socket clientSocket = new Socket();
// we try to establish a connection, timeout is three seconds
clientSocket.connect(new InetSocketAddress(target, 80), 3 * 1000);
// talk to the server
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
out.println(&quot;GET / HTTP/1.1&quot;);
out.println(&quot;Host: stackoverflow.com&quot;);
out.println(&quot;&quot;);
out.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String t;
while ((t = br.readLine()) != null) System.out.println(t); // We print the answer of the server
br.close();
clientSocket.close();
// server seems to be alive
System.out.println(&quot;&gt; Server is alive&quot;);
} catch (SocketTimeoutException | ConnectException e) {
System.out.println(&quot;&gt; Server is dead&quot;);
} catch (Exception e) { // This is not nice but this is also just a demo
e.printStackTrace();
}
}
}
}

Output (excerpt):

Try to connect to: 192.168.168.1
&gt; Server is dead
Try to connect to: 192.168.168.2
&gt; Server is dead
...
Try to connect to: 192.168.168.23
(answer of the server)
&gt; Server is alive
...

huangapple
  • 本文由 发表于 2020年10月25日 02:59:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64516986.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定