首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java HttpServer读取超时,来自同一应用的后续请求彼此太近

Java HttpServer读取超时,来自同一应用的后续请求彼此太近
EN

Stack Overflow用户
提问于 2018-06-13 05:08:09
回答 1查看 957关注 0票数 0

由于java HttpServer的一个问题,我快疯了。我创建具有上下文等功能的服务器,然后从客户端应用程序使用URLConnectionInputStream连接到服务器。

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

我已经尝试过使用Executor(同时使用Executors.newCachedThreadPool()Executors.newFixedThreadPool(10),,但什么也没有使用。

另一件奇怪的事情是使用两个客户端:

  1. Client 1: first request = ok
  2. Client 2: first request = ok
  3. WAIT first SECONDS
  4. Client 1: second request = ok
  5. Client 1: third request = freeze (参见下面的代码),然后发送
  6. 2: second request = ok (当client 1仍在尝试并超时时)

<>G225

所以..。问题似乎与特定的客户端实例有关

这里有一些代码

服务器

代码语言:javascript
复制
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);
    }

上下文是通过添加的

代码语言:javascript
复制
server.createContext("/empty", new HttpHandler_Empty(this));

客户端

这是执行请求的函数

代码语言:javascript
复制
 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次尝试的代码)

代码语言:javascript
复制
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();
    }

}

和错误

代码语言:javascript
复制
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)

那会是什么呢?你有什么建议来避免这个问题吗?非常感谢你提前

EN

回答 1

Stack Overflow用户

发布于 2018-06-13 06:01:50

我不知道这个问题的原因。但是我决定使用Apache Java HTTP Client Library

下面是代码

代码语言:javascript
复制
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();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50825845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档