【问题标题】:How to detect end of Input Stream from Socket using BufferedInputStream?如何使用 BufferedInputStream 从 Socket 检测输入流的结束?
【发布时间】:2016-09-13 01:36:17
【问题描述】:

我正在尝试从 Java 中的 Socket 读取和输入,然后通过调用函数对其进行处理。我必须按字节而不是按文本阅读,因为由于来自客户端的请求,作为文本阅读会产生一些错误。所以我决定使用BufferedInputStream这个类。问题是没有检测到请求的结束。我猜这是因为流并没有结束只是被绞死或其他什么......

根据documentationread() 函数返回从流中读取的字节,如果流已经结束,则返回-1。因此,我的代码逐字节读取,将其加入一个字符串,然后,当流结束时,发送要处理的字符串(或者至少应该这样做)。代码如下:

BufferedInputStream reader = new BufferedInputStream(socket.getInputStream());
int dt;   
String cmd = "";

while( (dt = reader.read()) >= 0){
  cmd += (char)dt == '\n' || (char)dt == '\r' ? ' ' : (char)dt; // add each byte read to the string 
  System.out.println(cmd);
}

processaInput(cmd);

问题是函数processaInput 永远不会被调用,就像程序卡在循环中一样。但更奇怪的是,它并没有卡在循环中,因为 system.out.println 在流结束后停止被调用。顺便说一句,这是在线程(run()函数)中运行的,不知道这是否会搞砸,所以我在这里添加了最后一条信息。无论如何,我在这里错过了什么?谢谢。

编辑:没有客户端代码,因为我正在使用来自 google 的应用程序 POSTMAN 对其进行测试,所以它只是向我的程序发送 HTTP 请求。

【问题讨论】:

标签: java sockets


【解决方案1】:

您将“请求结束”与“流结束”混为一谈。

套接字上的“流结束”表示对等方已关闭连接。没有流结束,没有对等关闭。如果您打算将响应写回此套接字,则首先尝试将其读取到流的末尾是不正确的。

您正在尝试读取单个请求,在这种情况下,您需要应用程序协议中的某些内容来告诉您何时拥有所有内容:行;一个长度词前缀;像 XML 这样的自描述协议; STX/ETX;类型长度值; ...

在这种情况下,如果协议是 HTTP,您需要实现 Content-length 标头:识别它,读取到标头的末尾,然后从流中准确读取那么多字节,例如与DataInputStream.readFully()

【讨论】:

  • ...您可能还必须处理分块传输编码。
猜你喜欢
  • 2012-06-22
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 2012-10-13
  • 1970-01-01
相关资源
最近更新 更多