繁体   English   中英

我的套接字客户端似乎仅从HTTP服务器收到了第一个响应。 为什么?

[英]My socket client only seems to receive the first response from a HTTP server. Why?

我正在尝试开发一个类,该类允许我在线程上运行套接字,并且可以随时让我通过它发送数据,以及在数据到达时接收通知。 它不应该采取任何措施,例如仅在第一次发送消息后才接收消息,等等。由于某种原因,以下代码仅对第一个请求打印响应:

public static void main(String[] args) throws IOException {
    TCPClient client = new TCPClient(new TCPClientObserver());
    client.connect("www.microsoft.com", 80);

    sleep(1000);
    client.send("HTTP GET");

    sleep(5000);
    client.send("XYZ");
}

印刷

echo: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
echo: <HTML><HEAD><TITLE>Bad Request</TITLE>
echo: <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
echo: <BODY><h2>Bad Request - Invalid URL</h2>
echo: <hr><p>HTTP Error 400. The request URL is invalid.</p>
echo: </BODY></HTML>

这是套接字的核心逻辑:

        echoSocket = new Socket("www.microsoft.com", 80);
        out = new PrintWriter(echoSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(
                echoSocket.getInputStream()));

        while (true) {
            String response = in.readLine();
            if (response != null)
                System.out.println("echo: " + response);
        }

我猜问题出在我的循环中?

我的应用程序的完整测试代码可以在这里找到: http : //codepad.org/bmHwct35

谢谢

问题不在于循环,而在于您发送的第一个请求。 “ HTTP GET”请求无效,服务器应以“ 400 Bad request”响应,然后关闭连接。 这就是为什么您没有收到第二条消息的回复的原因。 尝试使用有效的HTTP请求,例如“ GET / HTTP / 1.1 \\ r \\ nHost:www.microsoft.com \\ r \\ n \\ r \\ n”。 HTTP 1.1连接默认为保持活动状态,因此您可以发送其中的几个并接收后续响应。

问题在于HTTP服务器使用HTTP协议,而您的客户端代码未正确使用该协议。 相反,它是打开一个普通套接字并编写似乎基于猜测的随机内容。

本文档中指定了HTTP协议。 如果您阅读了该书,将会发现您正在做的事情与客户应该做的事情完全不同。

我建议您不要尝试以这种方式实现您的客户端。 从头开始实现HTTP协议的客户端工作量很大……而且世界上还不需要另一个简单的HTTP客户端。 您可以使用标准的URL / HttpURLConnection API,也可以使用第三方的HTTP客户端库。


在您的情况下,400响应很可能是发送格式错误的请求的结果。 HTTP GET请求(实际上是任何HTTP请求)应该在第一行中包含目标URL。 阅读规格。

您发送的第一个请求是无效请求,回复后服务器将关闭连接。 然后,在代码中,您将陷入while (true)循环中,因为当连接/流关闭(流的末尾到达)时,您将不断从readLine返回null

while (true) { // <-- never terminates
  String response = in.readLine();
  if (response != null) // <- now null all the time
    System.out.println("echo: " + response);
}

假设HTTP 400是您所期望的,那么如果readLine()返回null,则需要中断循环。 通常这样写:

while ((line = in.readLine()) != null)
{
    // ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM