問題:當(dāng)某個(gè)客戶端退出后,其他客戶端再發(fā)消息的時(shí)候,轉(zhuǎn)發(fā)就會報(bào)錯(cuò);
package com.huaxin.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class Myserver { public static ArrayList<ServerThread>list =new ArrayList<ServerThread>(); public void initServer() { try { //創(chuàng)建服務(wù)器對象,并指定端口號 ServerSocket server = new ServerSocket(9090); System.out.println("服務(wù)器已建立......"); //不斷獲得客戶真?zhèn)€連接 while(true){ Socket socket =server.accept(); System.out.println("客戶端連接進(jìn)來了......"); //當(dāng)有客戶端連接進(jìn)來以后,開啟1個(gè)線程,用來處理該客戶真?zhèn)€邏輯, ServerThread st = new ServerThread(socket); st.start(); //添加該客戶端到容器中 list.add(st); } } catch (Exception e) { e.printStackTrace(); } } }
package com.huaxin.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class ServerThread extends Thread { public Socket socket; public InputStream ins; public OutputStream ous; public ServerThread(Socket socket) { this.socket = socket; } public void run() { try { // 獲得輸入輸出流 ins = socket.getInputStream(); ous = socket.getOutputStream(); // 發(fā)送消息給客戶端 String msg = "welcome to zhou's server !"; sendMsg(ous, msg); // 發(fā)送要求登錄信息給客戶端 String userinfo = "please input your name:"; sendMsg(ous, userinfo); // 獲得客戶端輸入的用戶名 String userName = readMsg(ins); // 發(fā)送要求密碼信息給客戶端 String pwd = "please input your password:"; sendMsg(ous, pwd); // 獲得客戶端輸入的密碼 String pass = readMsg(ins); // 登錄驗(yàn)證 boolean falg = loginCheck(userName, pass); // 校驗(yàn)不通過時(shí),循環(huán)校驗(yàn) while (!falg) { msg = "Fail to connect server......"; sendMsg(ous, msg); msg = "please check your name and password and login again....."; sendMsg(ous, msg); msg = "please input your name:"; sendMsg(ous, msg); // 獲得客戶端輸入的用戶名 userName = readMsg(ins); // 發(fā)送要求密碼信息給客戶端 msg = "please input your password:"; sendMsg(ous, msg); // 獲得客戶端輸入的密碼 pass = readMsg(ins); falg = loginCheck(userName, pass); } // 校驗(yàn)成功后:開始聊天 msg = "successful connected..... you can chat with your friends now ......"; sendMsg(ous, msg); // 聊天處理邏輯 //讀取客戶端發(fā)來的消息 msg=readMsg(ins); //輸入bye結(jié)束聊天 while(!"bye".equals(msg)){ //給容器中的每一個(gè)對象轉(zhuǎn)發(fā)消息 for (int i = 0; i <Myserver.list.size(); i++) { ServerThread st =Myserver.list.get(i); //不該自己轉(zhuǎn)發(fā)消息 if(st!=this){ sendMsg(st.ous, userName+" is say:"+msg); } } //等待讀取下1次的消息 msg=readMsg(ins); } } catch (Exception e) { System.out.println("客戶端不正常關(guān)閉......"); // e.printStackTrace(); } //有異常后統(tǒng)1將流關(guān)閉 try { ins.close(); ous.close(); socket.close(); //將當(dāng)前已關(guān)閉的客戶端從容器中移除 Myserver.list.remove(this); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 校驗(yàn)客戶端輸入的賬號和密碼的函數(shù),由于沒有數(shù)據(jù)庫,暫時(shí)寫死了 public boolean loginCheck(String name, String pwd) { if (name.equals("zhou") && pwd.equals("zhou") || name.equals("user") && pwd.equals("pwd") || name.equals("huaxinjiaoyu") && pwd.equals("huaxinjiaoyu")) { return true; } return false; } // 發(fā)送消息的函數(shù) public void sendMsg(OutputStream os, String s) throws IOException { // 向客戶端輸出信息 byte[] bytes = s.getBytes(); os.write(bytes); os.write(13); os.write(10); os.flush(); } // 讀取客戶端輸入數(shù)據(jù)的函數(shù) public String readMsg(InputStream ins) throws Exception { // 讀取客戶真?zhèn)€信息 int value = ins.read(); // 讀取整行 讀取到回車(13)換行(10)時(shí)停止讀 String str = ""; while (value != 10) { // 點(diǎn)擊關(guān)閉客戶端時(shí)會返回⑴值 if (value == ⑴) { throw new Exception(); } str = str + ((char) value); value = ins.read(); } str = str.trim(); return str; } }
package com.huaxin.server; public class Test { public static void main(String[] args) { Myserver ms = new Myserver(); ms.initServer(); } }
上一篇 <Oday安全 11.6利用加載模塊之外的地址繞過SafeSEH>一節(jié)注記---jmp [ebp+N] (上)
下一篇 springMVC源碼解析--HandlerMethodArgumentResolverComposite參數(shù)解析器集合(二)