[英]Manage all incoming chat messages in java socket programming
我正在開發一個具有聊天功能的程序,我正在其中使用套接字。 就我而言,我想在不同的窗口聊天中處理每個客戶端(請參閱附加圖片)。
截至目前,當連接1個客戶端時,沒有問題。 但是當連接了 2 個客戶端時,第一個客戶端將被第二個覆蓋,除非我關閉最新連接的客戶端的連接,否則他無法從服務器接收消息(服務器仍然接收來自所有客戶端的消息,盡管只有 1 個客戶端可以從服務器接收)。
我要怎么做? 我正在使用船長 casa 框架,我想像下圖那樣管理它。
這是我的代碼:服務器:
public void mainserver(){
Thread server = new Thread(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
System.out.println("Server Online... \nWaiting for Connections");
} catch (IOException e) {
e.printStackTrace();
}
while (accept){
try {
socket = serverSocket.accept();
System.out.println("New Connection Estasblished!!!");
chatHandler chat = new chatHandler(socket);
chat.start();
} catch (IOException e) {
System.out.println("server not terminate all connections");
System.exit(-1);
}
}
}
});
server.start();
}
public class chatHandler extends Thread{
Socket socket;
public chatHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
dout.writeUTF("Hi! Thank you for reaching us! How may I help you!?");
while (!read.equals(".end")){
read = din.readUTF();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+read);
}else {
setServerArea(read);
}
}
System.out.println("end of chat server");
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("Exit");
try {
dout.close();
din.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void serverSend(javax.faces.event.ActionEvent event) { // "Send" button
write = getServerField();
try {
dout.writeUTF(write);
dout.flush();
if (getServerArea()!=null){
setServerArea(getServerArea()+"\n"+write);
setServerField("");
}else {
setServerArea(write);
setServerField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
客戶:
public void client(){
Thread client = new Thread(new Runnable() {
@Override
public void run() {
try {
socket = new Socket("localhost",port);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
while (!read.equals("bye")){
read = din.readUTF();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+read);
}else {
setClientArea(read);
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
din.close();
dout.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
client.start();
}
public void clientSend(javax.faces.event.ActionEvent event) {
write = getClientField();
try {
dout.writeUTF(write);
dout.flush();
if (getClientArea()!=null){
setClientArea(getClientArea()+"\n"+write);
setClientField("");
}else {
setClientArea(write);
setClientField("");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(write);
}
我相信我理解這個問題,以及如何糾正它。
您為每個新連接使用唯一的線程 (chatHandler)。
該線程在連接時自動寫入“Hello”,但此后專門用於讀取消息(在 while 循環中您只讀取 din)並相應地更新控制台。 由於每個線程都在管理對 din 的引用,因此所有傳入的消息都可以。
但是,寫回客戶端(serverSend)似乎不在線程中; 它由按鈕事件觸發。 此時,dout 將是對最近連接的引用,而不是對打算獲取消息的客戶端的引用。 這就是為什么最近的客戶端會收到所有未來的消息。
更正是為目標客戶選擇正確的“dout”。 當服務器“操作員”選擇寫回消息(單擊發送按鈕)時,您需要以某種方式為該客戶端獲取正確的“dout”。
一種方法是在創建線程之前建立dout(使用socket),並維護每個客戶端之間的關系,以及它對應的dout(即在Map中)。
如果問題仍然不明確(每個客戶必須有一個唯一的 Dout 引用),請告訴我,我會盡力澄清。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.