繁体   English   中英

从Servlet请求输入流读取时套接字超时

[英]Socket Timeout while reading from Servlet request inputstream

我有一段代码从Servlet Request的输入流中读取POST数据。 我正在使用java nio读取数据。

对于大多数情况和常规数据,该代码可以正常工作。 但是,在某些情况下,数据量很大( content length = 600000 ),通道的读取方法似乎因套接字超时错误而失败。 同样,这似乎仅发生在IE 9上,它在Firefox和Chrome上运行良好。

在调查这一点时,我发现使用IE时,发布数据似乎比其他浏览器可读取的时间更长。 所以我在代码之前放了一个Thread.sleep(400) ,代码也开始对IE正常工作。

我不想在这段代码之前睡个懒觉,一个只是一种解决方法,而不是一个适当的解决方案,其次,没有正确的睡眠时间,因为如果数据增加,则400可能不够。

有没有一种方法可以告诉频道不要超时或完全取消超时?

下面是正在使用的代码,

ReadableByteChannel channel = Channels.newChannel(inputStream);
byte[] postData = new byte[contentLength];
ByteBuffer buf = ByteBuffer.allocateDirect(contentLength);
int numRead = 0;
int counter = 0;
while (numRead >= 0) {
    buf.rewind();
    numRead = channel.read(buf);
    buf.rewind();
    for (int i = 0; i < numRead; i++) {
       postData[counter++] = buf.get();
    }
}
return postData;

inputStream直接通过request.getInputStream()进行,内容长度通过request.getContentLength()进行。

所使用的容器是嵌入式模式下的Tomcat 7.0.42。

您的读取超时时间太短。 增加它。

但是我会丢掉这个NIO代码,而直接从输入流中读取。 使用DataInputStream.readFully(),它是一行代码。 无论如何,您的NIO代码都会执行此操作,但会以非常round回的方式进行,并带有几个额外的层。

如果您可以读取内容长度标头,则可以基于它增加睡眠时间。 那至少应该使您的代码在不同的情况下起作用。 当然,这是一种解决方法,但似乎很可靠。 另外,您可以将套接字超时等待设置为更高的数字 但是,此更改将适用于所有servlet,并且灵活性较差。

由于我找不到适合此问题的任何解决方案。 我继续进行现有的工作,例如睡眠一段时间。 但是我的问题是我要睡多长时间,因为数据量越大,我就需要睡得更多。 而且,没有正确的方法知道这一点,因为我无法从内容长度中得出任何公式,因此睡眠时间是随机的。

因此,我可以应用的下一个最佳选择是,我捕获了Socket Timeout Exception,并睡眠了我知道所需的最少最短时间,即400ms。 然后再次尝试,在放弃之前设置3次重试的逻辑。 到目前为止,这种方法已经可以工作,可以增加数据量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM