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

相关文章
相关标签/搜索