Java網絡編程案例---聊天室

  網絡編程是指編寫運行在多個設備(計算機)的程序,這些設備都經過網絡鏈接起來。html

  java.net包中JavaSE的API包含有類和接口,它們提供低層次的通訊細節。你能夠直接使用這些類和接口,來專一於解決問題,而不用關注通訊細節。java

  java.net包中提供了兩種常見的網絡協議的支持:編程

  TCP:TCP是傳輸控制協議的縮寫,它保障了兩個應用程序之間的可靠通訊。一般用於互聯網協議,被稱TCP/IP。服務器

  UDP:UDP是用戶數據報協議的縮寫,一個無鏈接的協議。提供了應用程序之間要發送的數據的數據報。網絡

  本案例以TCP協議爲例,結合多線程,實現一個多人同時聊天的聊天室。多線程

  釋放資源:ide

  Utils.javathis

 1 package com.bjwyj.chat;  2 
 3 import java.io.Closeable;  4 
 5 public class Utils {  6     /**
 7  * 釋放資源  8      */
 9     public static void close(Closeable... targets) { 10         for(Closeable target:targets) { 11             try { 12                 if(target!=null) { 13  target.close(); 14  } 15             }catch(Exception e) { 16  e.printStackTrace(); 17  } 18  } 19  } 20 }

  服務器端:spa

  Chat.java.net

 1 package com.bjwyj.chat;  2 
 3 import java.io.DataInputStream;  4 import java.io.DataOutputStream;  5 import java.io.IOException;  6 import java.net.ServerSocket;  7 import java.net.Socket;  8 import java.util.concurrent.CopyOnWriteArrayList;  9 
 10 /**
 11  * 在線聊天室:服務端  12  * 目標:加入容器實現羣聊和私聊  13  *  14  * @author 吳永吉  15  *  16  */
 17 public class Chat {  18     private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<>();  19     public static void main(String[] args) throws IOException {  20         System.out.println("------server------");  21         //1.指定端口:使用ServerSocket建立服務器
 22         ServerSocket server = new ServerSocket(9999);  23         //2.阻塞式等待鏈接accept
 24         while(true) {  25             Socket client = server.accept();  26             System.out.println("一個客戶端創建了鏈接");  27             Channel c = new Channel(client);  28             all.add(c); //管理全部的成員
 29             new Thread(c).start();  30  }  31  }  32     //一個客戶表明一個Channel
 33     static class Channel implements Runnable{  34         private DataInputStream dis;  35         private DataOutputStream dos;  36         private Socket client;  37         private boolean isRunning;  38         private String name;  39         
 40         public Channel(Socket client) {  41             isRunning = true;  42             this.client = client;  43             try {  44                 dis = new DataInputStream(client.getInputStream());  45                 dos = new DataOutputStream(client.getOutputStream());  46                 //獲取名稱
 47                 this.name = receive();  48                 //歡迎你的到來
 49                 this.send("歡迎上線");  50                 this.sendOthers(this.name+"上線啦!",true);  51             }catch(Exception e) {  52  release();  53  }  54  }  55         
 56         //接收消息
 57         public String receive() {  58             String msg = "";  59             try {  60                 msg = dis.readUTF();  61             } catch (IOException e) {  62                 System.out.println("-------Chat receive------");  63  release();  64  }  65             return msg;  66  }  67         //發送消息
 68         public void send(String msg) {  69             try {  70  dos.writeUTF(msg);  71  dos.flush();  72             } catch (IOException e) {  73                 System.out.println("--------Chat send-------");  74  release();  75  }  76  }  77         /**
 78  * 羣聊:獲取本身的消息,發給其餘人  79  * 私聊:約定數據格式:@xxx:msg  80  * @param msg  81          */
 82         public void sendOthers(String msg,boolean isSys) {  83             boolean isPrivate = msg.startsWith("@");  84             if(isPrivate) { //私聊
 85                 int idx = msg.indexOf(":");  86                 //獲取目標和數據
 87                 String targetName = msg.substring(1,idx);  88                 msg = msg.substring(idx+1);  89                 for(Channel other:all) {  90                     if(other.name.equals(targetName)) { //目標
 91                         other.send(this.name+"悄悄的對你說:"+msg);  92                         break;  93  }  94  }  95             }else { //羣聊
 96                 for(Channel other:all) {  97                     if(this==other) { //本身
 98                         continue;  99  } 100                     if(!isSys) { 101                         other.send(this.name+"對全部人說:"+msg); //羣聊消息
102                     }else { 103                         other.send(msg); //系統消息
104  } 105  } 106  } 107  } 108         //關閉資源
109         public void release() { 110             this.isRunning = false; 111  Utils.close(dis,dos,client); 112             //退出
113             all.remove(this); 114             sendOthers(this.name+"下線了!",true); 115  } 116 
117  @Override 118         public void run() { 119             while(isRunning) { 120                 String msg = receive(); 121                 if(!msg.equals("")) { 122                     //send(msg);
123                     sendOthers(msg,false); 124  } 125  } 126  } 127  } 128 }

  客戶端:

  Send.java

 1 package com.bjwyj.chat;  2 
 3 import java.io.BufferedReader;  4 import java.io.DataOutputStream;  5 import java.io.IOException;  6 import java.io.InputStreamReader;  7 import java.net.Socket;  8 
 9 /**
10  * 使用多線程封裝了客戶發送端: 11  * 1.發送消息 12  * 2.從控制檯獲取消息 13  * 3.釋放資源 14  * 4.重寫run 15  * @author 吳永吉 16  * 17  */
18 public class Send implements Runnable{ 19     private BufferedReader console; 20     private DataOutputStream dos; 21     private Socket client; 22     private boolean isRunning; 23     private String name; 24     
25     public Send(Socket client,String name) { 26         isRunning = true; 27         this.client = client; 28         this.name = name; 29         console = new BufferedReader(new InputStreamReader(System.in)); 30         try { 31             dos = new DataOutputStream(client.getOutputStream()); 32             //發送名稱
33  send(name); 34         } catch (IOException e) { 35             System.out.println("------Client Send------"); 36             this.release(); 37  } 38  } 39     
40  @Override 41     public void run() { 42         while(isRunning) { 43             String msg = this.getStringFromConsole(); 44             if(!msg.equals("")) { 45                 this.send(msg); 46  } 47  } 48  } 49     
50     /**
51  * 發送消息 52      */
53     private void send(String msg) { 54         try { 55  dos.writeUTF(msg); 56  dos.flush(); 57         } catch (IOException e) { 58             System.out.println("------Client send------"); 59  release(); 60  } 61  } 62     
63     /**
64  * 從控制檯獲取消息 65      */
66     private String getStringFromConsole() { 67         try { 68             return console.readLine(); 69         } catch (IOException e) { 70             System.out.println("------Client console------"); 71  release(); 72  } 73         return ""; 74  } 75     
76     //釋放資源
77     private void release() { 78         this.isRunning = false; 79  Utils.close(dos,client); 80  } 81 }

  Receive.java

 1 package com.bjwyj.chat;  2 
 3 import java.io.DataInputStream;  4 import java.io.IOException;  5 import java.net.Socket;  6 
 7 /**
 8  * 使用多線程封裝了客戶接收端  9  * 1.接收消息 10  * 2.釋放資源 11  * 3.重寫run 12  * @author 吳永吉 13  * 14  */
15 public class Receive implements Runnable{ 16     private DataInputStream dis; 17     private Socket client; 18     private boolean isRunning; 19     
20     public Receive(Socket client) { 21         this.isRunning = true; 22         this.client = client; 23         try { 24             dis = new DataInputStream(client.getInputStream()); 25         } catch (IOException e) { 26             System.out.println("------Client Receive------"); 27             this.release(); 28  } 29  } 30     
31     //接收消息
32     public String receive() { 33         String msg = ""; 34         try { 35             msg = dis.readUTF(); 36         } catch (IOException e) { 37             System.out.println("-------Receive receive------"); 38  release(); 39  } 40         return msg; 41  } 42     
43  @Override 44     public void run() { 45         while(isRunning) { 46             String msg = this.receive(); 47             if(!msg.equals("")) { 48  System.out.println(msg); 49  } 50  } 51  } 52     
53     //釋放資源
54     private void release() { 55         this.isRunning = false; 56  Utils.close(dis,client); 57  } 58 }

  Client.java

 1 package com.bjwyj.chat;  2 
 3 import java.io.BufferedReader;  4 import java.io.IOException;  5 import java.io.InputStreamReader;  6 import java.net.Socket;  7 import java.net.UnknownHostException;  8 
 9 /**
10  * 在線聊天室:客戶端 11  * 12  * @author 吳永吉 13  * 14  */
15 public class Client { 16     public static void main(String[] args) throws UnknownHostException, IOException { 17         System.out.println("------client------"); 18         BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 19         System.out.println("請輸入名稱:"); 20         String name = br.readLine(); 21         //創建鏈接:使用Socket建立客戶端+服務器的地址和端口號
22         Socket client = new Socket("localhost",9999); 23         //客戶端發送消息
24         new Thread(new Send(client,name)).start(); 25         //獲取消息
26         new Thread(new Receive(client)).start(); 27  } 28 }

  運行結果:

原文出處:https://www.cnblogs.com/wuyongji/p/10659540.html

相關文章
相關標籤/搜索