2016-11-03 49 views
0

this question嘗試此代碼。當請求stackoverflow.com時,它給出了正確的答覆,但是當我嘗試https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket時,它返回HTTP/1.1 400 Bad Request。什麼導致這個問題?Java套接字獲取HTTP/1.1 400錯誤請求

這是我從上面的鏈接得到的正確的響應從服務器得到的工作代碼。

Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80); 
PrintWriter pw = new PrintWriter(s.getOutputStream()); 
pw.println("GET/HTTP/1.1"); 
pw.println("Host: stackoverflow.com"); 
pw.println(""); 
pw.flush(); 
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
String t; 
while ((t = br.readLine()) != null) { 
    System.out.println(t); 
} 
br.close(); 

試圖將其更改爲以下...

Socket s = new Socket(InetAddress.getByName("stackoverflow.com"), 80); 
PrintWriter pw = new PrintWriter(s.getOutputStream()); 
pw.println("GET/HTTP/1.1"); 
pw.println("Host: https://stackoverflow.com/questions/10673684/send-http-request-manually-via-socket"); 
pw.println(""); 
pw.flush(); 
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
String t; 
while ((t = br.readLine()) != null) { 
    System.out.println(t); 
} 

則響應爲HTTP/1.1 400 Bad Request

P.S.我不打算使用任何http庫。

+2

主機應該保持在工作代碼中,但您必須將主機上方的行更改爲GET/questions/10673684/send-http-request-manually-via-socket HTTP/1.1' – Alex

+1

@Alex您應該將該評論作爲回答 – tddmonkey

+0

Hi @Alex。你是對的。非常感謝。如果你會提出答案,我會標記它。 – beginner

回答

1

問題在於你的要求,這是不正確的。如果你用

pw.println ("GET /questions/10673684/send-http-request-manually-via-socket HTTP/1.1"); 
pw.println ("Host: stackoverflow.com"); 

替換你的電話到PrintWriter它應該工作。


編輯: 作爲EJP在這個答案評論指出,應確保線路的結局總是\r\n。你既可以溝的println功能,轉而使用

pw.print ("Host: stackoverflow.com\r\n"); 

you could change the default line ending to make sure println works correctly,然而,這可能會影響你的程序的其他部分也是如此。


此外,你可以使用try-與資源,以確保你讀完後,既解決了他對你的問題的評論斯特芬Ullrichs關注的問題之一的插座被關閉。

但是,在您的第一個示例中,您可以調用br.close();,它應該關閉底層輸入流,然後關閉套接字,這樣也可以工作。但是,在我看來,最好明確地做到這一點。

+2

除非您至少修復了行終止,這是* not *使用'println()'的問題。您可能會對一系列容忍的HTTP服務器感到幸運,但任何HTTP服務器都有權忽略/拒絕僅基於該請求的請求。 – EJP

+0

我試圖解決您在編輯中的擔憂。如果需要,您仍然可以使用'println()',您只需在創建PrintWriter實例之前設置line.separator屬性。 – Alex

相關問題