【问题标题】:Cannot see data from a simple Java Proxy Server看不到来自简单 Java 代理服务器的数据
【发布时间】:2017-07-17 15:08:18
【问题描述】:

我已经实现了一个简单的代理服务来窃听发往和发自微服务(MS)的消息。它基本上有一个 ServerSocket 监听传入连接并通过 Socket 连接将请求转发到 MS。

它还接收来自 MS 的响应并将其转发给客户端。

我正在窃听这些消息并暂时将它们打印出来。 (我打算稍后做其他验证工作)

但是,我的问题是我没有在响应中看到 MS 返回的数据本身。我只看到 HTTP 标头详细信息。

例子:

1.从客户端到代理

curl http://localhost:9099/anrl/hello/Kandy2

2. proxy-service 收到上述请求后打印的消息:

Incoming from Client [95] bytes --------------->
 GET /anrl/hello/Kandy2 HTTP/1.1
Host: localhost:9099
User-Agent: curl/7.51.0
Accept: */*

-----------------------

3.代理服务打印的来自 MS 的响应

Incoming from Server [82] bytes --------------->
 GET /anrl/hello/Kandy2 HTTP/1.1
Host: localhost:9099
User-Agent: curl/7.51.0
Accept: */*

-----------------------
Incoming from Server [14] bytes --------------->
 GET /anrl/hello/Kandy2 HTTP/1.1
Host: localhost:9099
User-Agent: curl/7.51.0
Accept: */*

-----------------------
java.net.SocketException: Socket closed
   at java.net.SocketInputStream.socketRead0(Native Method)
   at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
   at java.net.SocketInputStream.read(SocketInputStream.java:170)
   at java.net.SocketInputStream.read(SocketInputStream.java:141)
   at java.net.SocketInputStream.read(SocketInputStream.java:127)
   at shabir.mcgill.proxy.service.ProxyService.runServer(ProxyService.java:124)
   at shabir.mcgill.proxy.service.ProxyService.main(ProxyService.java:32)

4.在客户端控制台中打印的响应

Hello Kandy2.

我希望在上面 (3) 中打印的输出之一中看到响应消息 ('Hello Kandy2.') .但是,我在那里看不到任何东西。但是,预期的响应似乎到达了我的客户端程序(上例中的 cURL),并且正在整齐地打印出来,如 (4) 所示。

另外,我在想最后的exception是什么意思?

被这行抛出:

while ((bytes_read = from_server.read(replyBuffer)) != -1) 

但是,这不会停止将响应传递给客户端。

谁能帮我了解这里发生了什么,以及我如何从代理服务从 客户端微服务

------------
编辑

我没有从流中检索任何标题信息。我只是从 Socket 流中读取所有字节并打印出来。

final InputStream from_client = client.getInputStream();
final InputStream from_server = server.getInputStream();

while ((bytes_read = from_client.read(requestBuffer)) != -1) {
    to_server.write(requestBuffer, 0, bytes_read);
    System.out.println("Incoming from Client [" + bytes_read + "] bytes --------------->\n " +
    new String(requestBuffer, Charsets.UTF_8) + "-----------------------");
    to_server.flush();
}


while ((bytes_read = from_server.read(replyBuffer)) != -1) {
    try {
        Thread.sleep(1);
        System.out.println("Incoming from Server [" + bytes_read + "] bytes --------------->\n " +
        new String(requestBuffer, Charsets.UTF_8) + "-----------------------");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    to_client.write(replyBuffer, 0, bytes_read);
    to_client.flush();
}

谢谢
沙比尔

【问题讨论】:

  • 向我们展示更多代码。就像你如何检索标题一样......
  • @UsagiMiyamoto - 我已经包含了关于如何阅读和打印信息的代码部分。 clientserver 是两个 Socket 对象。
  • new String(buffer, "UTF-8") 调用可能会失败,因为您的读取可能发生在多字节编码的 unicode 字符的中间。好吧,它会默默地失败,但不一定会显示发送的内容。
  • @JamesKPolk 是的,就查看数据而言,这也是我认为的问题所在。有任何建议提示我如何才能最好地阅读内容以便也能看到数据?
  • @JamesKPolk 发现问题。不是我们想的那样。见下文。

标签: java sockets curl networking proxy


【解决方案1】:

找到问题的答案:

  1. 我在 sout 中没有看到任何数据的原因是,在第二个循环中:

我从 服务 读取到 reply_buffer,但正在打印 request_buffer .因此,如果您看到 (3),它会一遍又一遍地打印相同的内容。通过打印出正确的 reply_buffer,我得到了预期的以下信息:

-----------------------
Incoming from Server [82] bytes --------------->
 HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 15
Content-Type: *//*

-----------------------
Incoming from Server [15] bytes --------------->
 Hello Kandy2..

Connection: keep-alive
Content-Length: 15
Content-Type: */*

-----------------------
  1. exception 的原因是因为程序无法知道服务器端已经关闭了它的连接,除非在尝试读取时抛出一个异常来表明这一点。这是因为代理服务无法知道还剩下多少数据或这是否是传入数据的最后一位。

    正如in this stack-overflow thread 解释的那样,唯一的选择是捕获异常并优雅地通过,或者从服务器分配一个特殊令牌,以指示这是发送的最后一位数据。

谢谢大家
沙比尔

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 2018-01-01
    • 2012-02-16
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多