我有一个非常基本的测试应用程序,该应用程序从内存中提供字节并将其返回给客户端。
每当我尝试发送超过2 GB的字节大小的请求时,我的服务器代码都会收到连接重置错误,而我的chrome控制台则出现502错误。低于2 GB可以正常工作。
在客户端,我执行从浏览器执行的Java脚本。这基本上执行XMLHTTPRequest,获取响应(存储在浏览器内存中)并请求保存。
想知道为什么会发生错误。是因为超出了浏览器选项卡的内存限制吗?
下面是servlet或服务器端代码
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String param = request.getParameter("size");
if (param != null) {
int kByte = Integer.parseInt(param);
response.setContentType("application/octet-stream");
response.setContentLength(kByte * 1024);
ServletOutputStream outputStream = response.getOutputStream();
byte[] buffer = new byte[1024];
Random random = new Random(System.currentTimeMillis());
long size = 0;
while (size < kByte) {
random.nextBytes(buffer);
outputStream.write(buffer);
size += 1;
}
outputStream.flush();
return;
}
}catch (Exception e) {
e.printStackTrace();
response.sendError(500, e.getMessage());
return;
}
}
下面是我的测试客户端Java脚本代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href='https://fonts.googleapis.com/css?family=Titillium+Web:400' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
margin: 0;
font-family: "Titillium Web";
font-size: 15px;
}
#demo-container {
width: 400px;
margin: 60px auto;
}
#download-button {
background-color: white;
color: #2980b9;
border: 2px solid #2980b9;
font-family: inherit;
outline: none;
min-width: 100px;
padding: 10px;
font-size: inherit;
border-radius: 2px;
cursor: pointer;
display: block;
margin: 0 auto;
}
#start-download {
text-align: center;
display: none;
}
#download-progress-container {
border: 1px solid #cccccc;
padding: 4px;
display: none;
height: 20px;
}
#download-progress {
background-color: #2980b9;
display: inline-block;
height: 100%;
}
#save-file {
color: #2980b9;
text-decoration: none;
display: none;
text-align: center;
}
#save-file:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id="demo-container">
<button id="download-button">Download</button>
<div id="download-ui-container">
<div id="start-download">Starting Download..</div>
<div id="download-progress-container"><div id="download-progress"></div></div>
<a id="save-file">Save File</a>
</div>
</div>
<script>
var _OBJECT_URL;
document.querySelector('#download-button').addEventListener('click', function() {
var request = new XMLHttpRequest();
request.onload = function () {
_OBJECT_URL = URL.createObjectURL(request.response);
document.querySelector('#save-file').setAttribute('href', _OBJECT_URL);
document.querySelector('#save-file').setAttribute('download', 'networkTester');
document.querySelector('#save-file').style.display = 'block';
document.querySelector('#download-progress-container').style.display = 'none';
setTimeout(function() {
window.URL.revokeObjectURL(_OBJECT_URL);
document.querySelector('#download-button').style.display = 'block';
document.querySelector('#save-file').style.display = 'none';
}, 60*1000);
}
request.responseType = 'blob';
//request.open('get', 'img.jpeg');
request.open('get', 'server url?size=4000000');
request.send();
});
</script>
</body>
</html>
服务器端的堆栈跟踪
2019-03-20T10:32:28.501+0000 [APP/PROC/WEB/0] ERR org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:364)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:833)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:738)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:399)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:377)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.saurav.cpcftester.NetworkTester.doGet(NetworkTester.java:52)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:364)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:170)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at com.sap.xs.java.valves.ErrorReportValve.invoke(ErrorReportValve.java:66)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at com.sap.xs.security.UserInfoValve.invoke(UserInfoValve.java:19)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at com.sap.xs.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:43)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at com.sap.xs.logging.catalina.RuntimeInfoValve.invoke(RuntimeInfoValve.java:40)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:679)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at java.lang.Thread.run(Thread.java:836)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR Caused by: java.io.IOException: Connection reset by peer
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:50)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at sun.nio.ch.IOUtil.write(IOUtil.java:65)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:478)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:134)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:157)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.doWrite(NioEndpoint.java:1306)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.SocketWrapperBase.doWrite(SocketWrapperBase.java:726)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.SocketWrapperBase.writeBlocking(SocketWrapperBase.java:496)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.tomcat.util.net.SocketWrapperBase.write(SocketWrapperBase.java:434)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.http11.Http11OutputBuffer$SocketOutputBuffer.doWrite(Http11OutputBuffer.java:623)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:127)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.http11.Http11OutputBuffer.doWrite(Http11OutputBuffer.java:225)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.coyote.Response.doWrite(Response.java:602)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:352)
2019-03-20T10:32:28.502+0000 [APP/PROC/WEB/0] ERR ... 39 more
最好的问候,
Saurav
答案 0 :(得分:1)
可能是遇到整数溢出的情况。具体来说,该行:
response.setContentLength(kByte * 1024);
可以接受一个有符号整数范围,因此2^31-1 = (2147483647 bytes)
可能会导致溢出。
您可以尝试像这样修复它:
long length = kByte * 1024;
if (length <= Integer.MAX_VALUE)
{
response.setContentLength((int)length);
}
else
{
response.addHeader("Content-Length", Long.toString(length));
}
如reference中所述。