2016-10-09 29 views
-1

我想在JAVA中編寫我的HttpServer。網絡上的性能編碼

有一個簡單的代碼用於創建套接字(服務器和客戶端)並讀取和收集頭信息,一旦用戶編寫了一個URL。

我正在尋找一種可以操縱獲取/收集數據的好方法(性能代碼)。

在我寫的代碼中,我填充了它,看起來很糟糕。
也許誰可以幫我解釋關於第三級的嘗試塊爲寫一個好的代碼?

例如,我認爲if (headerTempData.contains("\r\n\r\n")) break;它會減慢數據流並從連接的套接字收集數據,因爲我不知道將下載多少標題行以及它檢查的所有門控信息。

也許誰知道相關的文獻(書即),可以幫助我理解爲HTTP協議很有助於我

感謝的代碼性能良好的額外點!

具體try塊代碼:

try (InputStream raw = socket.getInputStream()) { 

    String headerTempData = ""; 

    // chain the InputStream to a Reader 
    Reader reader = new InputStreamReader(raw); 

    int c; 
    while ((c = reader.read()) != -1) { 
     headerTempData += (char) c; 
     System.out.print((char) c); 

     if (headerTempData.contains("\r\n\r\n")) 
      break; 
    } 

    System.out.println("- - - - - - - - - - - - EOL - - - - - - - - - - - -"); 

} 

所有的代碼示例:

package pk7HttpServer; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.MalformedURLException; 
import java.net.ServerSocket; 
import java.net.Socket; 

/** 
* Created by Morris on 08/10/16. 
*/ 
public class HTTPServer { 


    public static void main(String[] args) { 

     new HTTPServer().startServer(); 
    } 

    public void startServer() { 

     try (ServerSocket serverSocket = new ServerSocket(8080)) { 

      System.out.println("Server is started"); 

      while (true) { 
       Socket socket = serverSocket.accept(); 

       try { 
        try (InputStream raw = socket.getInputStream()) { 

         String headerTempData = ""; 

         // chain the InputStream to a Reader 
         Reader reader = new InputStreamReader(raw); 

         int c; 
         while ((c = reader.read()) != -1) { 
          headerTempData += (char) c; 
          System.out.print((char) c); 

          if (headerTempData.contains("\r\n\r\n")) 
           break; 
         } 

         System.out.println("- - - - - - - - - - - - EOL - - - - - - - - - - - -"); 

        } 
       } catch (MalformedURLException ex) { 
        System.err.println(socket.getLocalAddress() + " is not a parseable URL"); 

       } catch (IOException ex) { 
        System.err.println(ex.getMessage()); 
       } 
      } 

     } catch (Exception ex) { 
      System.out.println("error# " + ex.getMessage()); 
     } 
    } 
} 
+2

你測試過了嗎?是什麼讓你認爲你的方式效率低下?這聽起來像過早的優化,這是浪費時間的候選人。當你知道確實存在效率問題時,專注於優化。 –

+1

這是爲了一堂課還是解決一個真正的問題? – chrylis

+0

服務器通常應該服務於許多客戶端。因此,您應該將從serverSocket.accept()接收到的套接字傳遞給爲其提供此請求的自己的線程。最主要的原因是可以接受()以準備接受另一個客戶的下一個請求。 – Heri

回答

1

您解析邏輯有幾個缺點。

  1. 發件人可能以塊的形式傳輸數據。這意味着可能是read()返回-1,儘管整個輸入尚未收到。如果尚未達到預期的數據末尾,則必須實施邏輯以重新輸入read()。
  2. 將每個字節轉換爲char(您沒有提供要使用的字符集,因此您的代碼在Windows和Linux計算機上的行爲不同)是耗時的操作。因此,您可以在收到的每個字節上調用contains()(這是另一個耗時的操作)。
  3. 我建議以塊(例如1024字節)讀取傳入數據,並且只有在您認爲現在有足夠的數據將字節數組轉換爲字符串時,才使用已定義的CharacterSet來聚合它。
  4. \ r \ n是窗口上的換行符。在其他平臺上,這是不同的。
  5. 只要收到的數據小於contains-call的長度,它永遠不會是真的。只有收到足夠的數據時才檢查標題結尾。
+0

我知道我的代碼中有些不好。感謝您的詳細解答。 – morris