簡體   English   中英

使用Java中的套接字向服務器發送請求

[英]sending request to server using socket in java

我正在使用套接字與服務器建立流連接。 通過創建套接字,我嘗試使用套接字向服務器發送請求。 但是無論我使用哪種方法,服務器都不會收到請求。 這些是我用來發送請求的方法。

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(query);

或另一個是

 out = new ObjectOutputStream(connection.getOutputStream());
 out.writeObject(msg);
 out.flush();

我嘗試發送的請求是這樣的:

String query = String.format("cmd=%s&version=%s", "handshake", "1.0");

我知道使用Httpconnection發送此查詢要容易得多,但這是必須完成的方法。 所以請幫我 這是httpconnection命令

 String charset = "UTF-8";
 String query = String.format("cmd=%s&version=%s", "handshake", "1.0");
 String charset = "UTF-8";
 URL url = new URL("serveraddress:8080");           
 URLConnection conn = url.openConnection();         
 conn.setDoOutput(true);            
 conn.connect();            
 OutputStream output = conn.getOutputStream();              
 output.write(command.getBytes(charset));                                       

 InputStreamReader content = new InputStreamReader(conn.getInputStream());                              
 String result ="";
 int c = content.read();
 while (c != -1) {
    result = result + ((char) c);  
        c = content.read();
} 
 Log.v(logTag, "Received: [" + result + "]");

這是我在插座上做的沒用的

 URL url = new URL("serveraddress:8080");               
 String server_name = url.getHost();
 int port = url.getPort();
 Socket socket = new Socket(server_name, port);                         

 String query = "post /swarm HTTP/1.1\nHost: serveraddress\n" +
 "content-length: 27\nkeep-alive: 300\nconnection: keep-alive\n\n" +
 "cmd=handshake&version=1.0\n"; 

 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
 out.println(query);

根據服務器日志,套接字連接在沒有任何請求的情況下打開和關閉

您提到的三種方法(PrintWriter,ObjectOutputStream和HTTPConnection)都會導致將某些內容發送到服務器,但是實際發送的內容在各種方法之間將有很大的不同。

首先,Java ObjectOutputStream類將對您寫入其的對象進行編碼 ,並提供有關這些對象所屬的類的信息,尤其是類名,簽名等。這實際上僅在與另一個Java應用程序通信時才適用在另一端使用ObjectInputStream讀取它。 它尤其不會遵循HTTP協議,因此,您很可能根本無法使用HTTPConnection來使用它。

使用HttpURLConnection實際上將構造完整的(最重要的是有效的)HTTP請求並將其發送到您嘗試連接的服務器。 例如,如果您要執行以下代碼:

URL url = new URL("http://localhost/test?cmd=handshake&version=1.0");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();

然后結果將是您的應用程序連接到localhost:80並編寫如下內容:(這是一個簡化的請求。實際請求中將包含其他標頭和信息。)

GET /test?cmd=handshake&version=1.0 HTTP/1.1
Host: localhost

最后,如果您使用的是PrintWriter ,則實際上會將純文本發送到服務器。 但是,如果服務器是HTTP服務器(可能是因為您說它響應HTTP連接),則僅發送請求的命令部分是不夠的。 您還必須發送其余部分,包括GET ,HTTP版本,可能的一些標頭,尾隨的空行和CRLF行的結尾。 所有這些都可以使用PrintWriter完成。

安裝諸如Wireshark之​​類的網絡數據包分析器並使用它來實際查看在使用httpconnection執行連接時發送到服務器的內容,然后嘗試通過手動構造請求來模仿它是一個好主意。

我還建議您閱讀有關HTTP協議的更多詳細信息。 一個很好的起點可以是Wikipedia文章

根據OP中的新信息進行編輯:

更新的代碼中存在一些小的不一致之處,我可以認為其中一些是復制粘貼錯誤,而我想指出的是一些以防萬一。

基於URLConnection的解決方案沒有在任何地方指定“ / swarm”資源。 添加該內容不會更改請求是否實際發送,也不會更改請求的有效性,但這可能會影響您是否可以在日志中找到該請求。

除了使用小寫字母編寫POST之外,查詢字符串總體上看起來是合理的。 最初我並不認為這會有所作為,但是當嘗試通過Telnet針對www.google.com進行“獲取”與“獲取”時,似乎沒有什么不同。 如果Web服務器無法將該請求識別為請求,則它將無法處理該請求,因此它可能不會如您期望的那樣顯示在日志中。

我建議您實際閱讀服務器響應並將其打印到System.out,以便查看服務器是否報告任何特定錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM