課堂練習:
服務器端和客戶端通信:
服務器端
package day16; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class ServerSocketDemo { public static void main(String[] args) { try { ServerSocket ss=new ServerSocket(1234); System.out.println("服務啓動"); while(true){ Socket socket=ss.accept(); System.out.println("連接進來了"); /*InetAddress ssadd=socket.getInetAddress(); String hostname=ssadd.getHostName(); String addr=ssadd.getHostAddress(); byte[] bytes=ssadd.getAddress(); System.out.println("socket.getInetAddress()= "+ssadd+"; ssadd.getHostName()= "+hostname+"; sadd.getHostAddress()= "+bytes); int port=socket.getPort(); System.out.println("正在接受 "+ssadd+": 的請求");*/ InputStream is=socket.getInputStream(); OutputStream os= socket.getOutputStream(); //讀取 BufferedReader br=new BufferedReader(new InputStreamReader(is,"gbk")); //寫入 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"gbk")); String line=null; while((line=br.readLine())!=null){ System.out.println("服務端收到數據 "+line); String send="Hello "+line+"\r\n"; bw.write(send); bw.flush(); } } } catch (IOException e) { e.printStackTrace(); } } }
客戶端:
package day16; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientSocketDemo { public static void main(String[] args) { try { Socket socket=new Socket("localhost", 1234); System.out.println("SOCKET"); //輸入 InputStream is=socket.getInputStream(); //輸出 OutputStream os= socket.getOutputStream(); //讀取 BufferedReader br=new BufferedReader(new InputStreamReader(is,"gbk")); //寫入 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"gbk")); //寫入數據 bw.write("abc! \r\n"); bw.flush(); System.out.println("客戶端收到數據 "+br.readLine()); bw.close(); /*while((line=br.readLine())!=null){ System.out.println("客戶端收到數據 "+line); bw.write("abc!"); }*/ } catch (Exception e) { } } }
運行結果:
/** * 服務器端: * 服務啓動 * 連接進來了 * 服務端收到數據 abc! * * * 客戶端: * 客戶端收到數據 Hello abc! */
2.QQ服務端GUI界面
3.在分線程中完成ServerSocket推送消息給所有客戶端。
List<OutputStream> ... = ;
代碼部分(MessageReceiverThread.java)
package day16.QQ_simpleDemo; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; import java.util.ArrayList; import java.util.List; /** * 消息接收線程 * @author a5967 * */ public class MessageReceiverThread extends Thread{ private QQGUI qqGUI; private Socket sock; private List<OutputStream> oslist=new ArrayList<OutputStream>(); private MessageServer server; public MessageReceiverThread(QQGUI qqGUI,Socket sock){ this.qqGUI=qqGUI; this.sock=sock; } public void run(){ while(true){ try { BufferedReader br=new BufferedReader(new InputStreamReader(sock.getInputStream(), "gbk")); String line=null; while((line=br.readLine())!=null){ server=new MessageServer(qqGUI); //更新推送的輸出流 server.UpdatOutputStreamList(sock); //更新聊天區域 qqGUI.updateHistory(SocketUtil.getAddr(sock),line); } } catch (Exception e) { e.printStackTrace(); } } } }
代碼部分(MessageServer.java)
package day16.QQ_simpleDemo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class MessageServer { private QQGUI qqGUI; //客戶端集合 private List<String> clients=new ArrayList<String>(); //輸出流所有含有輸出流線程的對象 private static List<OutputStream> oslist=new ArrayList<OutputStream>(); public MessageServer(QQGUI qqGUI) { this.qqGUI=qqGUI; } public QQGUI getQqGUI() { return qqGUI; } public void setQqGUI(QQGUI qqGUI) { this.qqGUI = qqGUI; } //啓動消息服務器 public void start(int port){ try { ServerSocket ss=new ServerSocket(port); System.out.println("服務器啓動"); //遠程的地址 InetAddress rmaddress; //遠程端口 int rmport=0; while(true){ final Socket sock=ss.accept(); //更新OutpurStream集合 new MessageReceiverThread(this.qqGUI,sock).start(); rmaddress=sock.getInetAddress(); rmport=sock.getPort(); //添加最新的聯繫人 clients.add(rmaddress.getHostName()+" : "+rmport); //刷新列表 qqGUI.addcontact(clients); } } catch (Exception e) { } } /** * 推送消息 * @param string */ public void pushMessage() { try { BufferedWriter bw=null; int a=oslist.size(); if(oslist.size()>0){ for(OutputStream clientos:oslist){ bw=new BufferedWriter(new OutputStreamWriter(clientos,"gbk")); bw.write("有新人進入聊天室 \r\n"); bw.flush(); System.out.println("服務端推送數據數據結束"); } } } catch (Exception e) { e.printStackTrace(); } } /** * 更新OutputStream集合 * @param sock */ public void UpdatOutputStreamList(Socket sock) { OutputStream os; try { os = sock.getOutputStream(); oslist.add(os); } catch (IOException e) { e.printStackTrace(); } } }
運行結果:
/** * 部分運行結果 * 服務器部分: * 服務器啓動 * 服務開始推發送數據 * 服務端推送數據數據結束 * 服務端推發數據完成 * 服務開始推發送數據 * 服務端推送數據數據結束 * 服務端推發數據完成 * 。。。 * * 客戶端部分(三個客戶端爲例) * 客戶端1 第1個連接進入的客戶端 * 您已成功進入聊天室 * 客戶端收到數據 有新人進入聊天室 * 客戶端收到數據 有新人進入聊天室 * * 客戶端2 第2個連接進入的客戶端 * 您已成功進入聊天室 * 客戶端收到數據 有新人進入聊天室 * * 客戶端3 第3個連接進入的客戶端 * 您已成功進入聊天室 */
4.推送聯繫人列表給所有客戶端。
部分代碼:
/** * 推送最新的信息人列表給各個客戶端 * @param newclientlist */ public void pushNewContactList(List<String> newclientlist) { try { BufferedWriter bw=null; int a=oslist.size(); if(oslist.size()>0){ for(OutputStream clientos:oslist){ bw=new BufferedWriter(new OutputStreamWriter(clientos,"gbk")); bw.write("當前聯繫人有\r\n"); for(String contact:newclientlist){ bw.write(contact+"\r\n"); bw.flush(); } System.out.println("服務端推送當前聯繫人列表數據結束"); } } } catch (Exception e) { e.printStackTrace(); } } /** * 部分運行結果 * 服務器啓動 * 服務開始推發送數據 * 服務端推送數據數據結束 * 服務端推發數據完成 * 服務端推送當前聯繫人列表數據結束 * 。。。 * * * 客戶端部分(三個客戶端爲例) * 客戶端1 第1個連接進入的客戶端 * 您已成功進入聊天室 * 客戶端收到數據 當前聯繫人有 * 客戶端收到數據 127.0.0.1 : 50709 * 客戶端收到數據 有新人進入聊天室 * 客戶端收到數據 當前聯繫人有 * 客戶端收到數據 127.0.0.1 : 50712 * 客戶端收到數據 127.0.0.1 : 50709 * 客戶端收到數據 有新人進入聊天室 * 客戶端收到數據 當前聯繫人有 * 客戶端收到數據 127.0.0.1 : 50712 * 客戶端收到數據 127.0.0.1 : 50713 * 客戶端收到數據 127.0.0.1 : 50709 * * 客戶端2 第2個連接進入的客戶端 * 您已成功進入聊天室 *客戶端收到數據 當前聯繫人有 *客戶端收到數據 127.0.0.1 : 50825 *客戶端收到數據 127.0.0.1 : 50827 *客戶端收到數據 有新人進入聊天室 *客戶端收到數據 當前聯繫人有 *客戶端收到數據 127.0.0.1 : 50825 *客戶端收到數據 127.0.0.1 : 50827 *客戶端收到數據 127.0.0.1 : 50828 * * 客戶端3 第3個連接進入的客戶端 * 您已成功進入聊天室 *客戶端收到數據 當前聯繫人有 *客戶端收到數據 127.0.0.1 : 50825 *客戶端收到數據 127.0.0.1 : 50827 *客戶端收到數據 127.0.0.1 : 50828 */