【问题标题】:Socket OutputStream::write method mixes TCP packets?Socket OutputStream::write 方法混合 TCP 数据包?
【发布时间】:2015-11-22 05:47:07
【问题描述】:

我对 java 套接字有一些问题。

我创建了一个简单的代理服务器,它监听 http 请求,将此请求传输到源,然后返回响应,而不会断开连接。有时客户端会收到无效数据。我查看了 tcp 转储日志,发现 tcp 数据包是混合的

这是一个非常简单的代码示例

Socket socket = new Socket("127.0.0.1", 3000);

OutputStream out = socket.getOutputStream();
InputStream in = socket.getInputStream();

while (true) {
    final Request request = Request.read(in);
    if (request == null) return;

    try {
        // send http request 
        HttpRequest httpRequest = HttpRequest.factory(request);
        Response response = httpRequest.response();

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();

        buffer.write(response.headers.toString());
        buffer.write(response.body);

        out.write(buffer.toByteArray());
        out.flush();
    } catch (ParserException | IOException e) {
        e.printStackTrace();
        return;
    }
}

这是一个屏幕tcp转储日志,你可以在一个tcp数据包中看到3个http响应http://dl2.joxi.net/drive/0009/2601/629289/150827/004858080b.jpg

为什么会发生这种情况,以及如何解决这个问题?

更新 28.10.2015 17:50

对不起,这是我在服务器端的错。 Java 完美运行

【问题讨论】:

  • 这个是没有办法写代理的。您正在引入各种不必要的延迟。所有这些 I/O 都可以直接在输出流中完成。 ByteArrayOutputStream 没有任何贡献。但是您也不需要 HTTP 请求对象。一旦你从客户端读取了第一行,剩下的就是来回复制字节。
  • 谢谢你的答案。这段代码非常非常简单,仅作为示例编写。在实际项目中,它不是简单的代理,而是多线程的多连接和大量的业务逻辑

标签: java sockets tcp


【解决方案1】:

您看到的是预期的正确行为。 Connection: keep-alive 标头意味着连接保持打开状态,以便它可以用于多个 HTTP 请求。如果它与流水线结合使用,响应甚至可能出现在单个 TCP 段中。

【讨论】:

  • 我赶紧祝贺:(。我删除了keep-alive,但这对我没有帮助:(
  • Keep-alive 是默认设置,您必须设置 Connection: close 以关闭连接。
  • 您能否提供一个显示问题的最小自包含示例?您上面的示例甚至没有创建 ServerSocket
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 2016-12-22
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多