2012-03-03 52 views
1

我想开发一个允许我在线程上运行套接字的类,并且在任何时候都允许我通过它发送数据,以及在数据到达时接收通知。应该假定没有的东西,如仅在接收到的消息已发送第一消息后,等 由于某种原因,下面的代码被打印为仅第一请求的响应:我的套接字客户端似乎只接收来自HTTP服务器的第一个响应。为什么?

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

感谢

回答

1

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

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

的问题是,HTTP服务器说话的HTTP协议,和您的客户端代码不能正常说话的协议。相反,它是打开一个普通的套接字和写随机的东西,似乎是基于猜测。

HTTP协议在this document中指定。如果你阅读它,你会发现你正在做的事与客户本应该做的不一样。

我建议你不要试图用这种方式实现你的客户端。从头开始实现HTTP协议的客户端太多了......而且这个世界并不需要另一个flak的HTTP客户端。可以使用标准的URL/HttpURLConnection API,也可以使用第三方HTTP客户端库。


在你的情况下,400的响应是最有可能发送恶意请求的结果。 HTTP GET请求(实际上是任何HTTP请求)应该包含第一行中的目标URL。阅读规范。

2

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

1

您发送的第一封是无效请求,服务器回复后将关闭连接。在您的代码中,您将被锁在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); 
} 
相关问题