Java HttpServer读取超时,来自同一应用程序的后续请求彼此过于靠近

时间:2018-06-12 21:08:09

标签: java http server timeout httpserver

由于java HttpServer 的问题,我发疯了。 我使用上下文等创建服务器,然后从客户端应用程序使用 URLConnection InputStream 连接到服务器。

问题是,当客户端执行更多后续请求彼此过于接近时,客户端会经常(没有明显的逻辑)获取读取超时。 为了避免这种情况,我必须从连接和下一个连接中放置 sleep(5000)(为什么5000?因为5000以下它仍然会超时)。

我已经尝试使用Executors(包含 Executors.newCachedThreadPool() Executors.newFixedThreadPool(10),但没有。

使用2个客户端的另一个奇怪的事情:

  1. 客户1:第一个请求= ok
  2. 客户2:第一次请求=确定
  3. 等待少量秒数
  4. 客户1:第二次请求=确定
  5. 客户端1:第三个请求=冻结,它继续尝试(参见下面的代码),然后给出超时
  6. 客户端2:第二个请求= ok(客户端1仍在尝试并且超时)
  7. 所以..问题似乎与特定的客户端实例有关

    这里有一些代码

    服务器

    try {
            cryptex = new ServerCryptex();
            final Executor multi = Executors.newCachedThreadPool();
            server = HttpServer.create(new InetSocketAddress(8888), 50);
    
            addContexts();
    
            server.setExecutor(multi);
            server.start();
    
    
        } catch (IOException ex) {
            Logger.getLogger(MyHttpServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    

    上下文添加了

    server.createContext("/empty", new HttpHandler_Empty(this));
    

    客户端

    这是执行请求的功能

     public byte[] performRequest(HashMap<String, String> params, String host, int port, String handler, boolean isConnectionEncrypted) throws IOException, InterruptedException {
        URL url = composeUrl(params, host, port, handler, isConnectionEncrypted);
        URLConnection con = url.openConnection();
        con.setConnectTimeout(300);
        con.setReadTimeout(7000);
        InputStream is = null;
    
        **NO PROBLEM UNTIL HERE**
    
        for (int i = 0; i < 5; i++) {
            try {
                System.out.println("open the stream, try #" + i);
    
                **TIMEOUT ON THE NEXT LINE**
    
                is = con.getInputStream();
                break;
            } catch (java.net.SocketTimeoutException ex) {
    
                **I THOUGHT TO USE THIS WAY TO TRY 5 TIMES THE CONNECTION BEFORE GIVING ERROR TO THE USER, BUT NOTHING. **
    
                sleep(500);
                if (i == 4) {
                    throw ex;
                }
            }
        }
        String reply = readReply(is);
        System.out.println("read reply:" + reply);
        if (isConnectionEncrypted) {
            return cryptex.decrypt(reply);
        } else {
            return reply.getBytes();
        }
    
    }
    

    真实代码(没有5次尝试代码)

    public byte[] performRequest(HashMap<String, String> params, String host, int port, String handler, boolean isConnectionEncrypted) throws IOException, InterruptedException {
        URL url = composeUrl(params, host, port, handler, isConnectionEncrypted);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setConnectTimeout(300);
        con.setReadTimeout(2000);
    
        System.out.println("open the stream");
        InputStream is = con.getInputStream();
    
        String reply = readReply(is);
        System.out.println("risposta letta:" + reply);
        if (isConnectionEncrypted) {
            return cryptex.decrypt(reply);
        } else {
            return reply.getBytes();
        }
    
    }
    

    错误

    giu 12, 2018 10:58:01 PM gui.Client_GUI aggiornaUdg
    GRAVE: null 
    java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1569)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
    at net.ClientConnector.performRequest(ClientConnector.java:96)
    at net.ClientConnector.checkKey(ClientConnector.java:43)
    at net.Client.getUDG(Client.java:56)
    at gui.Client_GUI.aggiornaUdg(Client_GUI.java:2407)
    at gui.Client_GUI.jButton1ActionPerformed(Client_GUI.java:1917)
    at gui.Client_GUI.access$000(Client_GUI.java:53)
    at gui.Client_GUI$1.actionPerformed(Client_GUI.java:390)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
    at java.awt.Component.processMouseEvent(Component.java:6533)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6298)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
    at java.awt.Container.dispatchEventImpl(Container.java:2280)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
    

    它可能是什么?你有什么建议可以避免这个问题吗? 非常感谢您提前

1 个答案:

答案 0 :(得分:0)

我不知道问题的原因..但我决定使用Apache Java HTTP Client Library

这里是代码

public byte[] performRequest(HashMap<String, String> params, String host, int port, String handler, boolean isConnectionEncrypted) throws IOException, InterruptedException {
    URL url = composeUrl(params, host, port, handler, isConnectionEncrypted);

    HttpClient client = HttpClientBuilder.create().build();
    HttpGet request = new HttpGet(url.toString());

    // add request header
    HttpResponse response = client.execute(request);

    System.out.println("Response Code : " + response.getStatusLine().getStatusCode());

    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

    String t = "";
    String s = rd.readLine();
    while (s != null) {
        t = t + s;
        s = rd.readLine();
    }

    System.out.println("risposta letta:" + t);
    if (isConnectionEncrypted) {
        return cryptex.decrypt(t);
    } else {
        return t.getBytes();
    }
}