Java网络编程案例---聊天室

  网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。

  java.net包中JavaSE的API包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。

  java.net包中提供了两种常见的网络协议的支持:

  TCP:TCP是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称TCP/IP。

  UDP:UDP是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据报。

  本案例以TCP协议为例,结合多线程,实现一个多人同时聊天的聊天室。

  释放资源:

  Utils.java

 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 }

  服务器端:

  Chat.java

  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

时间: 2024-11-08 11:35:40

Java网络编程案例---聊天室的相关文章

Java网络编程--简单聊天程序

背景 毕业设计前的练手,学校小比赛中的一个题目. 开发环境 Java(eclipse)+Mysql 简介 使用Java+Mysql开发以个简单的聊天工具,在本次项目中实现了: 1. 用户登录(客户端至服务器) 2. 登录服务器的用户可以公共聊天 3. 用户间可以实现私密聊天 下一次版本更新 实现同一账号只能一地登录. 界面 登录界面: 聊天主窗口: 私聊窗口:

Java 网络编程案例三:多个客户端上传文件

需求:每一个客户端启动后都可以给服务器上传一个文件,服务器接收到文件后保存到一个upload目录中.可以同时接收多个客户端的文件上传. 分析: (1)服务器端要“同时”处理多个客户端的请求,那么必须使用多线程,每一个客户端的通信需要单独的线程来处理. (2)服务器保存上传文件的目录只有一个upload,而每个客户端给服务器发送的文件可能重名,所以需要保证文件名的唯一.我们可以使用“时间戳”作为文件名,而后缀名不变 (3)客户端需要给服务器上传文件名(含后缀名)以及文件内容.而文件名是字符串,文件

Java网络编程 - 基于UDP协议 实现简单的聊天室程序

最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. 先看一下效果: 实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理. "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着. 看一下代码实现: 1.首先是消息服务器的实现,功能很简单: 将客户端的信息(进入了哪一个聊

JAVA网络编程UDP案例

Java网络编程.UDP案例 发送端 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class SendUDP { public static vo

Java网络编程(一)

Java网络编程: 1.1: 网络编程:对于我这个“研究不深”的网络菜鸟来说,我觉得网络编程就是实现计算机与计算机之间通信的编程.写些能够实现计算机与计算机之间的通信就行了(目前来说). 1.2:一台计算机跟另外计算机通讯. 计算机与计算机通讯的三大要素: 1:ip地址---电脑 1.1:作用:唯一标识一台计算机. 回环地址:127.0.0.1==主机:localhost 主机地址作用:测试网卡是否正常. 2:找到相应的应用程序----端口号 端口号-----具有网络功能的应用程序的标识号,没有

java socket控制台版本聊天室程序源码下载

原文:java socket控制台版本聊天室程序源码下载 代码下载地址:http://www.zuidaima.com/share/1550463257578496.htm java socket控制台版本聊天室程序源码下载,学习的时候写的,适合学习java基础 java网络编程基础用 标签: java socket 控制台 聊天室 源码话题: 网络编程 java socket控制台版本聊天室程序源码下载,布布扣,bubuko.com

一站式学习Java网络编程 全面理解BIO/NIO/AIO

第1章 [开宗明义]网络编程三剑客BIO.NIO.AIO网络编程是RPC的奠基,RPC编程贯穿了程序员生涯的始终.本章首先分析为什么要学网络编,本课为谁设计,然后介绍课程内容主线脉络,让大家清晰知道本课程并非光说不练的假把式,而是处处有实战,实战项目步步优化,最后通过综合项目巩固所学.... 第2章 网络层的解析与协议本章首先对网络中涉及的网络链路层的解析进行讲解,进一步引出网络基本协议知识.使学员了解分层思想,对三种协议的定位及作用有所了解. 第3章 解读java.io专业术语也可以变得生动精

Java网络编程基础【转】

网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电话号码,拨打电话嘛,很简单的事情啊!其实初学者如果入门网络编程的话也可以做到这么简单! 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.

第13篇-JAVA 网络编程

第13篇-JAVA 网络编程 每篇一句 比我强大的人都在努力我还有什么理由不拼命 初学心得 不去追逐你所渴求你将永远不会拥有 (笔者JEEP/711)[JAVA笔记 | 时间:2017-04-22| JAVA 网络编程 ] 1.网络编程基本概念 1.什么是计算机网络 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备通过通信线路连接起来在网络操作系统网络管理软件及网络通讯协议的管理和协调下实现资源共享和信息传递的计算机系统 把分布在不同地理区域的计算机与专门的外部设备用通讯线路互