2010-09-12 90 views
2

即時嘗試編寫一個簡單的Web服務器在Java中。java服務器來處理多個TCP連接

現在我只有一個簡單的程序,但id喜歡擴展它,以便它可以通過建立多個tcp連接服務於多個瀏覽器。

我一直在閱讀關於線程。我的理解是,你可以創建一個新的線程,並且這個線程將繼續,就像其他程序完全一樣。所以通過一個新的線程,它可以像2個可以服務2個瀏覽器的Web服務器,或者可以服務於X個Web瀏覽器的X個Web服務器。

即時通過在java中創建新線程併爲每個新線程建立連接丟失了一點點。

我的想法是,我將有一個這樣的循環,其獲得新的連接,並傳遞到一個新的線程每一個新的連接

// make new ServerSocket 
while (true) { 
    Socket newConn = serverSocket.accept(); 
    // make new thread, and pass in newConn 
} 

能有人給我如何推進一些指導? (此外,如果香港專業教育學院的地方犯了一個錯誤,請你指出來進出口新的線程編程所以它完全有可能的香港專業教育學院沒有正確地理解它。)

編輯:

ķ感謝所有。

我去寫了一些東西,這個java教程幫了很大忙。

香港專業教育學院有一個新的問題,現在

我在其中包含10秒倒計時(使用了Thread.sleep(1000)),每當服務器收到請求新線程添加一個循環,我的run()方法一個圖像,所以我可以看到哪些線程正在運行。 (index.html有4個圖像)

所以我要求index.html頁面和我的服務器工作正常。然後我打開了大約十幾個新標籤。我的期望是,對index.html頁面的請求將是即時的,但要將圖像發送到瀏覽器需要10秒(因爲我放在那裏的延遲),此時服務器將收到請求爲下一個index.html頁面,等等。總的來說,我認爲一打index.html頁面會立即提供,而4 * 12 = 36圖片需要10秒才能在所有選項卡上提供。

實際發生的事情是,需要10秒鐘才能獲得前4張圖像,接下來4張圖像需要10秒鐘等等,而不是服務多個網頁,我的服務器只是排隊處理請求並處理一頁一次。

我認爲我的程序有問題。但我覺得我可能無法正確理解瀏覽器如何與服務器交互。我認爲瀏覽器在html頁面被解析時請求新的對象。所以我的服務器應該會收到幾十個請求,如果我打開一打網頁。我試圖在FF中打開幾個選項卡,然後在FF中打開幾個窗口,但這並沒有幫助。然而,當我打開IE瀏覽器,FF和Chrome瀏覽器,並且我在不同的時間(間隔大約2秒)要求index.html時,它看起來像每個瀏覽器同時接收頁面,換句話說,在一個點,有12個不同的圖像正在服務,4對每個瀏覽器

所以我想即時通訊尋找一點確認,這是預期的行爲?如果是這樣,爲什麼我只能看到這種行爲,當我打開3個不同的瀏覽器,而不是當我打開多個選項卡?

(對於那些問,我計劃確定採取網絡課程明年,但我嘗試做一些基本的東西了。所以一半的自我學習,一半的H/W)

+0

這是作業/自學還是商業用途?如果是後者,我強烈建議使用[第三方HTTP服務器API](http://java-source.net/open-source/web-servers)而不是重新創建一個。 Jetty開始很好,它有JSP/Servlet支持。 – BalusC 2010-09-12 13:56:10

回答

1

您也可以考慮Netty和Java NIO。有多種方法可以做到這一點。

5

如果您正在尋找一些可靠的在線工作解決方案。
如果是爲了學習的目的,然後創建自己的。
有幾種方法可以做到這一點。最簡單的是這樣做,因爲從Java Tutorial採取:

import java.net.*; 
import java.io.*; 
public class MultiServer { 
    public static void main(String[] args) throws IOException { 
     ServerSocket serverSocket = null; 
     boolean listening = true; 

     try { 
      serverSocket = new ServerSocket(4444); 
     } catch (IOException e) { 
      System.err.println("Could not listen on port: 4444."); 
      System.exit(-1); 
     } 

     while (listening) 
     new MultiServerThread(serverSocket.accept()).start(); 

     serverSocket.close(); 
    } 
} 




import java.net.*; 
import java.io.*; 

public class MultiServerThread extends Thread { 
    private Socket socket = null; 
public MultiServerThread(Socket socket) { 
super("MultiServerThread"); 
this.socket = socket; 
} 

public void run() { 

try { 
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
    BufferedReader in = new BufferedReader(
       new InputStreamReader(
       socket.getInputStream())); 

    String inputLine, outputLine; 
    KnockKnockProtocol kkp = new KnockKnockProtocol(); 
    outputLine = kkp.processInput(null); 
    out.println(outputLine); 

    while ((inputLine = in.readLine()) != null) { 
    outputLine = kkp.processInput(inputLine); 
    out.println(outputLine); 
    if (outputLine.equals("Bye")) 
     break; 
    } 
    out.close(); 
    in.close(); 
    socket.close(); 

} catch (IOException e) { 
    e.printStackTrace(); 
} 
} 

}

你會實現你的邏輯在處理您的請求:

KnockKnockProtocol kkp = new KnockKnockProtocol(); 
outputLine = kkp.processInput(null); 

你可以通過把優化你的代碼你線程池中的線程,所以你不需要每次都創建一個新線程。

下面的部分是主觀的,取決於請求的類型以及您對每個請求的處理方式。 如果你有很多併發的客戶端請求,那麼NIO就是要走的路。
如果您的請求很短,並且您有超過10個併發請求創建池。
如果你的請求超過100,那麼我會開始看NIO。

0

Web服務器不過是一個帶消息傳遞的榮耀套接字服務器。自從第一次建立網絡連接以來,高科技就一直存在。大約一年半前,我有一個項目與你想要做的類似。 Java NIO是最好的選擇,具有連接和線程池以及Web服務器所需的所有高級功能,但它有點複雜。如果你想要一個非常好的基準開始,檢查出http://www.quickserver.org/我寫的系統是基於此,現在它處理了一臺服務器上的大約45,000個設備,最後我聽到了。

+0

Java NIO不*具有'連接和線程池',最好的開始是java.net。 – EJP 2010-09-13 00:25:58