0

我有一個java應用程序,人們可以登錄(並用數據庫做各種事情,但這不重要)。我可以使用.getInetAddress()獲取登錄到服務器的人員的IP地址,但是我不確定這些線程之間如何進行通信。我正在嘗試爲這個預先存在的程序添加聊天服務。如何在java中創建聊天客戶端

我的程序使用標準的多線程服務器,而clinet是單線程的AWT Action Listener程序。做這個的最好方式是什麼?我的代碼包含一個包含main的類,它創建一個新的「Client Handler」類並創建一個新線程來處理它。目前沒有線程間通信,線程會在其自己的套接字端口上生成並在服務器上獨立運行。我以前的想法包括:

使用ObjectInputStream將客戶端置於阻塞狀態,並等待客戶端接收消息(而不是忙於等待按鈕按下),並且條件是客戶端要執行一個動作(編輯一個字段),它將釋放阻塞I/O並執行該方法,然後返回到程序的阻塞I/O「等待」階段。

事情我不知道這一點:

  1. 如果我調用阻塞I/O,將AWT的ActionListener疏通阻塞I/O,並跳轉到事件處理程序?

  2. 如果客戶端在代碼中(而不是在阻塞的InputStream上)並且發送消息,服務器是否知道要等到程序返回inputStream之後才發送消息,或者是否會發送消息並創建一個隊列,或者更糟糕的是,問題。

  3. 服務器是多線程的,如果John位於192.168.1.100並且Larry位於192.168.1.152並且John想發送消息給Larry,那麼我如何從線程處理消息* .100到線程處理* .152,因此它可以輸出到正確的客戶端在正確的插座上。

我其他的想法(也許更容易之一)將是使客戶端多線程,連接到服務器的不同端口上,並使用一套完全不同的套接字連接來處理事件。在這種情況下,我可以使用阻塞I/O等待,當我得到消息時,輸出它,然後返回到阻塞I/O。生產代碼和聊天代碼之間的通信不會有任何問題,並且從這個立場來看它更好,但是這意味着我需要在連接的每個客戶端的不同端口上有2個打開的連接。該程序最終會同時連接數千個用戶,並且我不想用一個應用程序佔用所有服務器端口。

他們的其他方式是不是淹沒端口或冒通信錯誤?

回答

1

你的客戶端應該使用3個線程。所有的gui交互應該從EDT完成。然後,您應該有一個用於套接字InputStream的線程和一個用於套接字OutputStream的線程(這兩個塊都可能會阻塞)。當你想發送消息時,你的gui線程應該使用某種線程安全隊列將消息傳遞給OutputStream線程。 InputStream線程收到的任何消息都應該使用類似SwingUtilities.invokeLater的消息將消息推送到gui。

我不完全確定你在說什麼插座和端口。客戶端連接到服務器將需要一個單獨的套接字連接(這將涉及一個單獨的端口)

+0

@jtahlbom不熟悉SwingUtilities.invokeLater,但會看起來,當我有機會。使輸入/輸出流成爲一個獨立的類使得我以及線程安全的隊列成爲可能。儘管我接受了答案,但我希望看到其他人對此有何評論。我說的插槽是,如果我要分開生產代碼和聊天服務,並使用兩個不同的套接字連接來處理它們(每個套接字一個),我會使套接字要求翻倍。每個Cleint 2個,而不是每個客戶1個。 –

+0

@MattWestlake - 對不起,我不明白你的意思是把「生產代碼」從「聊天服務」中分離出來。你是通過同一個套接字發送多種類型的數據嗎?如果是這樣,你是否已經有2個其他線程管理讀/寫這個「其他」數據? – jtahlborn