2012-03-03 109 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); 
} 
相關問題