2014-11-06 97 views
2

我正在編寫一個消息傳遞程序,我遇到了一個難以理解如何將一個套接字傳遞給新的線程用於通過TCP處理出站消息。我目前正在使用UDP數據包處理來自客戶端的消息到服務器,該服務器作爲UDP,不需要太多處理,因爲它只是在傳入數據包時對數據進行反序列化並對其進行處理根據需要在一個單獨的線程中。我現在的問題是,我正在爲從服務器到連接的各種客戶端的反向流量設置一個客戶端啓動的TCP套接字。我已經做了一些研究,並且我已經理解每個客戶端應該有自己的線程來處理傳出的消息,以及另一個線程只是爲了接受傳入的連接。我不確定如何實現這個目標,並且我已經對這個主題進行了一些研究。在Java中處理多個TCP連接(服務器端)

我發現這一點:http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html

上述基本驗證了我原來懷疑,這必須由專用的客戶端線程處理資源。他們在這裏包含了僞代碼,它代表了我的偵聽器線程。

while (true) { 
    accept a connection; 
    create a thread to deal with the client; 
} 

我是一個視覺學習者,我一直在尋找某種類型的實例。我不確定將要傳遞給保持原始連接打開的線程的變量,並將數據推送回客戶端。我也遇到了一些麻煩,它們是否會保持相同的套接字打開,或者是否需要建立一個新套接字,這使我相信防火牆會干擾,但我知道這不會是案件。

有人能詳細解釋一下嗎?如果可能的話,一個例子將不勝感激!

我可能會在發佈後約15-30分鐘回覆並評論回覆。

+0

到處都有很多例子。從Oracle Java教程的自定義網絡部分開始。 – EJP 2014-11-06 22:24:03

+0

糾正我,如果我錯了,但不是我剛剛在問題中發佈的資源?我一直在尋找像教程這樣的東西,而我發現的所有東西都是簡單的1對1的溝通方式,相當於1對多。此外,我包含的代碼塊來自完全相同的教程。我在尋求幫助,理解如何實現這一點,在創建這個問題之前,我已經完成了你所看到的內容。 – Kristoff 2014-11-06 22:42:22

回答

2

你在做什麼聽起來正確。我通常實現這樣的(無客戶端的跟蹤等簡化版本)服務器:

@Override 
public void run() { 
    //start listening on the port 
    try { 
     serverSocket = new ServerSocket(port); 
     logger.info("Listening for connections on port " + port); 
    } catch (IOException e) { 
     logger.error("Cannot start SocketListener on port " + port + ". Stopping.", e); 
     return; 
    } 

    while (!stopped) { 
     try { 
      //wait for connection 
      Socket newSocket = serverSocket.accept(); 
      ClientThread client = new ClientThread(newSocket); 
      Thread clientThread = new Thread(client, MEANINGFUL_THREAD_ID); 
      clientThread.start(); 
     } catch ... 
    } 
} 

其中的ServerSocket是一個ServerSocket實例變量,並停止爲我用停止監聽線程的標誌。

因此,要在註釋中回答您的問題,您通常會將Socket對象傳遞給每個客戶端線程,以便該線程可以使用輸入和輸出流並處理關閉套接字等操作。一旦你「接受」了套接字連接,你不需要重新創建ServerSocket,你只需再次撥打.accept()開始等待新的連接。

在大多數情況下,您需要跟蹤服務器中的所有客戶端線程,以便您可以優雅地停止服務器或進行廣播。

+0

感謝您爲我解決這個問題。出於某種原因,我感覺你不能只將一個套接字的實例傳遞給另一個線程,重新建立與其他線程的連接,並讓其他線程正常工作。我也不知道如何正確傳遞它。 – Kristoff 2014-11-07 16:37:15

相關問題