java - Java HttpServer 读取超时,来自同一应用程序的后续请求彼此太近
问题描述
由于 java HttpServer的问题,我快疯了。我使用上下文等创建服务器,然后从客户端应用程序中使用带有InputStream的URLConnection连接到服务器。
问题是,当客户端执行更多的后续请求时,客户端经常(没有明显的逻辑)读取超时。为了避免这种情况,我必须从一个连接和下一个连接中放置一个sleep(5000)(为什么是 5000?因为在 5000 以下它仍然会超时)。
我已经尝试使用 Executors (同时使用Executors.newCachedThreadPool()和Executors.newFixedThreadPool(10),但没有。
使用 2 个客户端的另一个奇怪的事情:
- 客户端 1:第一个请求 = ok
- 客户端 2:第一个请求 = ok
- 等待几秒钟
- 客户端 1:第二个请求 = ok
- 客户端 1:第三个请求 = 冻结,它一直在尝试(参见下面的代码),然后给出超时
- 客户端 2:第二个请求 = ok(客户端 1 仍在尝试并超时)
所以..问题似乎与特定的客户端实例有关
这里有一些代码
服务器
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));
ETC
客户
这是执行请求的函数
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)
会是什么呢?你有什么建议可以避免这个问题吗?非常感谢您提前
解决方案
我不知道问题的原因..但我使用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();
}
}
推荐阅读
- java - 检查回文
- python - matplotlib 说 libpng16.so.16:无法打开共享对象文件:没有这样的文件或目录
- datetime - 试图找到一种方法来计算与 java8 重叠的 Jodatime 时刻
- usb - 在没有其他外部硬件的情况下更新 PIC 微控制器上的编程?
- css - 更改 flex-flow 包装列表的背景颜色
- node.js - 可选登录的身份验证方案
- asp.net - 将当前用户名(登录)保存到表单数据库 ASP.Net MVC
- r - 在 R 中进行减法时出现意外的输入错误
- javascript - 如何使用 Javascript 获取完整的画布内容(甚至是隐藏的内容)?
- angular - 树材质角2选中状态