【问题标题】:InputStream of a socket not readable套接字的 InputStream 不可读
【发布时间】:2014-03-07 14:46:27
【问题描述】:

我有一个 HTML 表单,它向我用 Java 制作的套接字发出 POST 请求。我用

阅读每一行
 /**
 * Read a line from an {@link InputStream}
 * @param inFromClient The {@link InputStream} to read from
 * @return The {@link String} read
 * @throws IOException When something went wrong while reading
 */
private String readLine(InputStream inFromClient) throws IOException {
    StringBuilder lineb = new StringBuilder();
    char c = (char) inFromClient.read();
    while (c != '\n'){
        lineb.append(Character.toString(c));
        c = (char) (inFromClient.read());        
    }
    String line = lineb.toString();
    return line.substring(0,line.lastIndexOf('\r')<0?0:line.lastIndexOf('\r'));
}

这样,我可以解析请求直到边界,然后保存发送的文件。一切正常。

但是,我也在尝试使用 Java 向同一个套接字发出 POST 请求。首先,我创建了一个连接到我的服务器套接字的第二个套接字。然后我做:

PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println("POST / HTTP/1.1");
pw.println("Host: ...");
...

问题

问题是,我的方法无法读取任何行,最终在第 5 行出现“OutOfMemory”异常。为什么我无法读取从 Java 套接字发送的行,而我可以读取从浏览器发送的行(html 表单)?谢谢。

【问题讨论】:

  • 为什么要附加Character.toString()StringBuilder 有一个 .append() 方法接受 char 作为参数...
  • 是的,你是对的,但这并不能解决问题

标签: java sockets post encoding outputstream


【解决方案1】:

您的服务器代码必须在转换为 char 之前将 read() 读入 int 并检查它是否为 -1。您将忽略流中的文件结尾并将 -1 附加到您的字符串生成器中。

但是:

  1. 我建议在您的服务器中使用现有的 HTTP 服务器框架来读取和解析请求,而不是自己编写。 (或者,如果您想使用自己的套接字代码,至少使用现成的 HTTP 请求解析器/响应序列化器。)

  2. 您的客户端和服务器代码都忽略字符编码。您需要使用 Charset 实例将字节转换为字符或从字符转换。

  3. 在您的客户端中使用 HttpURLConnection,而不是简单的 TCP 套接字。

  4. 最好使用 https://hc.apache.org/ 之类的东西来实现 HTTP 功能。

【讨论】:

  • 感谢您的回答。你会推荐我使用哪个框架?我需要一个可以在接收期间检测边界的解析器,然后使用 FileOutputStream 保存上传的文件。我不想等到上传结束。实际上,我正在构建一个流系统(从网页或 Android 应用程序流式传输)。此外,由于我只上传文件(二进制数据),我不明白需要字符编码。谢谢!
  • 不清楚您的网络服务器是否在 Android 上。如果没有,并且您想使用 Java,那么我会使用像 Jetty 或 Tomcat 这样的 servlet 容器来为我处理 HTTP。我使用 commons-fileupload 来处理二进制上传。同样,我会使用一个库来处理多部分的东西,而不是自己实现它。
  • 字符编码:HTTP 请求、标头和响应标头是文本的。您正在使用默认字符集(而不是明确使用 US-ASCII 或 UTF-8)使用 PrintWriter 生成 POST 请求,并将字节直接转换为服务器中的字符,这假定您的服务器的默认字符编码也是 ASCII -ish。尽管看起来,HTTP(加上多部分等)是一个相当复杂的协议,并且难以正确实现。
  • 我的网络服务器在 Raspberry Pi 上,我的客户端在 Android(第二个套接字)或 PC 上(网页,从 html 表单发布 http)。 Tomcat 不允许我在接收期间直接处理请求。
猜你喜欢
  • 2015-05-24
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 2012-02-04
  • 1970-01-01
  • 2013-04-19
  • 2015-07-07
  • 2013-11-19
相关资源
最近更新 更多