背景 : B站上 韓順平老師 QQ通訊軟體上 私聊所遇到的異常
起初看到老師 在服務端 使用 if() 語句判斷 客戶端 發送的message 對象 執行服務時 , 認為有點繁瑣
所以我將 if() 改為 switch 語句進行判斷 , 但是私聊功能只能使用一次
當使用第二次時會出現以下的異常 :
系統帶出有問題的代碼如下:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
我發現 原本類中的socket不能用新的socket取代 , 這樣while循環回來後會找不到原本的socket對應的通道 , 不知道這樣解釋有沒有問題
發現用將
socket = ManageThread.get(s).getSocket();改為socket2 , 並且使用對象輸出流 就沒有異常了
Socket socket2 = ManageThread.get(s).getSocket(); ObjectOutputStream oos2 = new ObjectOutputStream(socket2.getOutputStream());
case MessageType.MESSAGE_ALL: // 群聊
System.out.println(message.getSender() + "對大家說" + message.getContent());
ConcurrentHashMap<String, ConnectClient> hm = ManageThread.getHm();
Iterator<String> iterator = hm.keySet().iterator();
while (iterator.hasNext()){
String s = iterator.next();
socket = ManageThread.get(s).getSocket();
ObjectOutputStream oos2 = new ObjectOutputStream(socket.getOutputStream());
oos2.writeObject(message); // 轉發給對方
}
case MessageType.MESSAGE_ALL:
System.out.println(message.getSender() + "對大家說" + message.getContent());
ConcurrentHashMap<String, ConnectClient> hm = ManageThread.getHm();
Iterator<String> iterator = hm.keySet().iterator();
while (iterator.hasNext()){
String s = iterator.next();
ConnectClient connectClient = ManageThread.get(s);
ObjectOutputStream oos2 = new ObjectOutputStream(connectClient.getSocket().getOutputStream());
oos2.writeObject(message); // 轉發給對方
}
以下為我的switch 代碼 :
switch (message.getTpye()){
case MessageType.GET_ONLINE_LIST: // 獲取用戶列表
System.out.println(message.getSender() + " 要求在線用戶列表");
String onlineuser = ManageThread.getonlineuser();
Message message1 = new Message();
message1.setTpye(MessageType.RET_ONLINE_LIST);
message1.setContent(onlineuser);
message1.setGetter(message.getSender());
// 回傳
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message1);
break;
case MessageType.MESSAGE_COM: // 私聊
System.out.println(message.getSender() + "對" + message.getGetter() + "說" + message.getContent());
Socket socket1 = ManageThread.get(message.getGetter()).getSocket();
ObjectOutputStream oos1 = new ObjectOutputStream(socket1.getOutputStream());
oos1.writeObject(message); // 轉發給對方
break;
case MessageType.MESSAGE_ALL: // 群聊
System.out.println(message.getSender() + "對大家說" + message.getContent());
ConcurrentHashMap<String, ConnectClient> hm = ManageThread.getHm();
Iterator<String> iterator = hm.keySet().iterator();
while (iterator.hasNext()){
String s = iterator.next();
socket = ManageThread.get(s).getSocket();
ObjectOutputStream oos2 = new ObjectOutputStream(socket.getOutputStream());
oos2.writeObject(message); // 轉發給對方
}
break;
case MessageType.EXIT: // 客戶端要退出
System.out.println(message.getSender() + " 退出系統");
Thread.sleep(1000);
// 從集合刪除線程
ManageThread.remove(message.getSender());
// 關閉連結
socket.close();
// 退出線程
loop = false;
break;
}
以下為我的 if() 代碼:
if(message.getTpye().equals(MessageType.GET_ONLINE_LIST)){
System.out.println(message.getSender() + " 要求在線用戶列表");
String onlineuser = ManageThread.getonlineuser();
Message message1 = new Message();
message1.setTpye(MessageType.RET_ONLINE_LIST);
message1.setContent(onlineuser);
message1.setGetter(message.getSender());
// 回傳
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(message1);
}else if(message.getTpye().equals(MessageType.MESSAGE_COM)){
System.out.println(message.getSender() + "對" + message.getGetter() + "說" + message.getContent());
ConnectClient connectClient = ManageThread.get(message.getGetter());
ObjectOutputStream oos = new ObjectOutputStream(connectClient.getSocket().getOutputStream());
oos.writeObject(message); // 轉發給對方
}else if (message.getTpye().equals(MessageType.EXIT)){
System.out.println(message.getSender() + " 退出系統");
Thread.sleep(1000);
// 從集合刪除線程
ManageThread.remove(message.getSender());
// 關閉連結
socket.close();
// 退出線程
loop = false;
}else{
}