首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Java中,如何可靠地判断何时从套接字读取完毕?

在Java中,如何可靠地判断何时从套接字读取完毕?
EN

Stack Overflow用户
提问于 2010-08-05 02:39:33
回答 3查看 2.4K关注 0票数 1

我们正在与一个外部产品集成,该产品要求我们使用Java套接字与其通信。我们已经能够读取来自服务器的小响应,没有任何问题,但较大的响应会导致一些令人头疼的问题。

我对套接字处理逻辑进行了一些更改,现在我们似乎能够在90%的时间内读取大型响应。它仍然偶尔会失败。在这种情况下,失败意味着Java客户端在读取整个响应之前停止从套接字读取数据。客户端认为读取操作已完成,并正常停止-没有异常或超时。

下面是当前的逻辑:

代码语言:javascript
运行
复制
StringWriter response = new StringWriter();
PrintWriter writer = new PrintWriter(response);

char[] buf = new char[4096];
int readChars;
do {
   readChars = responseBufferedReader.read(buf);
   writer.write(buf, 0, readChars);
} while(readChars != -1 && responseBufferedReader.ready());

responseBufferedReader是一个包裹着InputStreamReaderBufferedReader,包裹着SocketInputStream

这段代码在大多数情况下都可以工作,但是检查readChars != -1ready()似乎不够可靠,无法指示我们是否已经读取了服务器上的所有内容。将读取的字符数与缓冲区大小进行比较也是不可靠的,因为服务器在发回响应时似乎有点慢,这会导致这些数字不同。

我试着改变了字符缓冲区的大小;这很有帮助,但它仍然不能百分之百地工作。

有没有一种更好、更可靠的方法来完全从Socket读取,而不需要知道预期响应的大小?我一直在做一些关于SocketChannel的研究,但我不确定更换是否会有任何好处。

为了以防万一,我们建立了一个到服务器的阻塞的Socket连接。Socket配置为100秒超时

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-05 02:59:20

您不应该检查BufferedReader是否就绪()来判断您是否完成了。可能仍在从线路上读取字节,而BufferedReader没有任何内容,但套接字尚未关闭。

我不确定BufferedReader给你带来了什么价值(好吧,它可能有助于你的表现)。我希望下面的方法能更好地工作:

代码语言:javascript
运行
复制
StringWriter response = new StringWriter();
PrintWriter writer = new PrintWriter(response);

char[] buf = new char[4096];
int readChars;
do {
   readChars = inputStreamReader.read(buf);
   writer.write(buf, 0, readChars);
} while(readChars != -1);

我认为,当网络成为瓶颈时,你可能会退出循环-循环处理结果的速度足够快,以至于Reader还没有准备好,而你认为你已经完成了阅读(即使你还没有准备好)。

票数 1
EN

Stack Overflow用户

发布于 2010-08-05 03:02:31

请访问Java blocking socket returning incomplete ByteBuffer查看问题的答案

如果网络将消息分解为数据包,您将在读取所有数据包之前退出循环。

票数 0
EN

Stack Overflow用户

发布于 2010-08-05 03:13:23

请看我对this question的回答。无论何时从流中读取,都适用相同的答案,如果EOF不适用(如本例所示),知道何时完成的唯一可靠方法是以某种方式在协议中对消息结尾进行编码--如何进行编码取决于您。

编辑:

如果您不能修改协议以包含消息边界,则可以研究基于超时的方法。您必须决定在检测到消息结束之前等待多长时间...但是,您必须处理在同一个流中获得两个消息的情况。你的代码现在能处理这种情况吗?如果是这样,那么您的答案是缓冲输入,并使用该逻辑来检测记录边界。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3408698

复制
相关文章

相似问题

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