2012-05-28 105 views
22

我目前正在創建一個返回靜態頁面<p>Hello!</p>小HTTP服務器...... 我試着用插座與Java:一個簡單的Http服務器與Java /套接字?

public static void main(String[] args) throws Exception { 

     // création de la socket 
     int port = 1989; 
     ServerSocket serverSocket = new ServerSocket(port); 
     System.err.println("Serveur lancé sur le port : " + port); 

     // repeatedly wait for connections, and process 
     while (true) { 

      // on reste bloqué sur l'attente d'une demande client 
      Socket clientSocket = serverSocket.accept(); 
      System.err.println("Nouveau client connecté"); 

      // on ouvre un flux de converation 

      BufferedReader in = new BufferedReader(
          new InputStreamReader(clientSocket.getInputStream()) 
         ); 
      PrintWriter out = new PrintWriter(
         new BufferedWriter(
          new OutputStreamWriter(clientSocket.getOutputStream())), 
         true); 

      // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur le flux d'écriture. 
      // la donnée lue est donc retournée exactement au même client. 
      String s; 
      while ((s = in.readLine()) != null) { 
       System.out.println(s); 


     out.write("HTTP/1.0 200 OK\r\n"); 
     out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"); 
     out.write("Server: Apache/0.8.4\r\n"); 
     out.write("Content-Type: text/html\r\n"); 
     out.write("Content-Length: 59\r\n"); 
     out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n"); 
     out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
     out.write("\r\n"); 
     out.write("<TITLE>Exemple</TITLE>"); 
     out.write("<P>Ceci est une page d'exemple.</P>"); 
    } 

      // on ferme les flux. 
      System.err.println("Connexion avec le client terminée"); 
      out.close(); 
      in.close(); 
      clientSocket.close(); 
     } 
    } 

這個代碼不包含任何錯誤,我從喜歡的瀏覽器的響應這個:

GET/HTTP/1.1 
Host: localhost:1989 
Connection: keep-alive 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Comodo_Dragon/19.0.3.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

但我的問題是,我沒有在瀏覽器頁面? 請幫忙嗎?

PS:我已經看過這篇文章:

回答

29

除了在每個請求標題行之後的\ r \ n,您必須在標題後面發送一個空行。例如:

out.write("HTTP/1.0 200 OK\r\n"); 
// Header... 
out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
out.write("\r\n"); // The content starts afters this empty line 
out.write("<TITLE>Hello!</TITLE>"); 
// Content... 

我糾正你的代碼,以便它的工作原理(但它仍然是不完美的,你應該處理在一個單獨的線程,例如用java.util.concurrent.ThreadPoolExecutor中的每一個請求):

public static void main(String[] args) throws Exception { 
    // création de la socket 
    int port = 1989; 
    ServerSocket serverSocket = new ServerSocket(port); 
    System.err.println("Serveur lancé sur le port : " + port); 

    // repeatedly wait for connections, and process 
    while (true) { 
     // on reste bloqué sur l'attente d'une demande client 
     Socket clientSocket = serverSocket.accept(); 
     System.err.println("Nouveau client connecté"); 

     // on ouvre un flux de converation 

     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
     BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); 

     // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur 
     // le flux d'écriture. 
     // la donnée lue est donc retournée exactement au même client. 
     String s; 
     while ((s = in.readLine()) != null) { 
      System.out.println(s); 
      if (s.isEmpty()) { 
       break; 
      } 
     } 

     out.write("HTTP/1.0 200 OK\r\n"); 
     out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"); 
     out.write("Server: Apache/0.8.4\r\n"); 
     out.write("Content-Type: text/html\r\n"); 
     out.write("Content-Length: 59\r\n"); 
     out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n"); 
     out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
     out.write("\r\n"); 
     out.write("<TITLE>Exemple</TITLE>"); 
     out.write("<P>Ceci est une page d'exemple.</P>"); 

     // on ferme les flux. 
     System.err.println("Connexion avec le client terminée"); 
     out.close(); 
     in.close(); 
     clientSocket.close(); 
    } 
} 
+1

我試過這個,但它仍然無法正常工作...(請參閱我的更新)。 –

+0

您的請求標題在循環錯誤時讀取。我將在我的答案中增加一個工作示例。 –

+0

Joel你忘了在你的例子中刷新輸出流。如果您嘗試使用大量HTML代碼,則無法正常工作。 –

1

什麼機器是您使用http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol,(對法國語言對不起......)?什麼OS?如果你運行的是UNIX機器,那麼println將不起作用,因爲它只發送一個LF字符。 HTTP的標題需要CR和LF。嘗試將\ r添加到字符串的末尾,看看是否有效。

哦,還有,你的:

out.println("HTTP/1.0 200 OK"+ 
"Date: Fri, 31 Dec 1999 23:59:59 GMT"+ 
"Server: Apache/0.8.4"+ 
"Content-Type: text/html"+ 
"Content-Length: 59"+ 
"Expires: Sat, 01 Jan 2000 00:59:59 GMT"+ 
"Last-modified: Fri, 09 Aug 1996 14:21:40 GMT"+ 

它的打印單,長字符串。

將它們更改爲每個字符串的println,或將\ r \ n添加到字符串中。

+0

謝謝!,我有Windows7,我試過這個但仍然不起作用.... –

+0

=> out.flush(); –

1

您需要在每行輸出之間使用正確的行分隔符(\r\n)。僅僅連接它們是不夠的 - 如果你打印出答覆,你可以看到它。

+0

他需要\ r \ n。這是HTTP。 – EJP

4

這只是對您最後一個問題的回答,而瀏覽器中沒有任何內容可見的原因是您計算錯誤的字符數。

它應該是57而不是59

更好的方法是具有自動計算字符數,但我相信你的樣本只是一個樣品。

+1

哦,那對我很有用。它應該在頂部:) –

相關問題