基于Socket实现多人聊天室
当前支持:
1.仅文字
2.加入聊天室提醒
3.退出聊天室提醒
可能出现的BUG:
1.可能出现客户端发送信息后不能及时推送,需要下一个客户端发送信息后一起推送
服务端代码:

1 package com.example.demo.socket;
2
3 import org.springframework.util.ObjectUtils;
4
5 import java.io.DataInputStream;
6 import java.io.DataOutputStream;
7 import java.io.IOException;
8 import java.net.ServerSocket;
9 import java.net.Socket;
10 import java.util.HashMap;
11 import java.util.Map;
12 import java.util.concurrent.*;
13
14 public class Server {
15 public static void main(String[] args) {
16 //信息队
17 ConcurrentLinkedQueue str = new ConcurrentLinkedQueue<>();
18 //连接对,暂未使用
19 ConcurrentLinkedQueue<Map> socket = new ConcurrentLinkedQueue<>();
20 //信息接收队
21 ConcurrentLinkedQueue<Map> ins = new ConcurrentLinkedQueue<>();
22 //信息发送队
23 ConcurrentLinkedQueue<Map> outs = new ConcurrentLinkedQueue<>();
24 //服务端端口号
25 int port = 6666;
26 try {
27 ServerSocket serverSocket = new ServerSocket(port);
28 //读取信息
29 new Thread(new Runnable() {
30 @Override
31 public void run() {
32 // 参数 4 可以根据实际服务器cup设置 一般IO密集型设置为 CUP+1
33 ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);
34 while (true) {
35 if(!ObjectUtils.isEmpty(ins.peek())) {
36 Map in = ins.poll();
37 //延迟10毫秒执行,执行周期为 实际线程执行时间+10毫秒
38 ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
39 @Override
40 public void run() {
41 try {
42 in.put("str", ((DataInputStream) in.get("in")).readUTF());
43 str.add(in);
44 } catch (IOException e) {
45 ((ScheduledFuture)in.get("future")).cancel(true);
46 }
47 }
48 }, 10, 10, TimeUnit.MICROSECONDS);
49 in.put("future",scheduledFuture);
50 }
51 }
52 }
53 }).start();
54 //发送信息
55 new Thread(new Runnable() {
56 @Override
57 public void run() {
58 while (true) {
59 if(!ObjectUtils.isEmpty(str.peek())) {
60 Map o = (Map) str.poll();
61 for(Map m : outs) {
62 if(!o.get("client").equals(m.get("client"))) {
63 try {
64 ((DataOutputStream)m.get("out")).writeUTF( o.get("client")+":"+o.get("str"));
65 } catch (IOException e) {
66 //异常下线大法,并发送群体下线通知
67 System.out.printf("%s下线了!\n",m.get("client"));
68 Map sv = new HashMap<>();
69 sv.put("client","server");
70 sv.put("str",m.get("client")+"退出聊天室!");
71 str.add(sv);
72 outs.remove(m);
73 }
74 }
75 }
76 }
77 }
78 }
79 }).start();
80 //循环获取客户端连接
81 while (true) {
82 Socket server = serverSocket.accept();
83 Map m = new HashMap<>();
84 m.put("socket",socket);
85 m.put("in",new DataInputStream(server.getInputStream()));
86 m.put("out",new DataOutputStream(server.getOutputStream()));
87
88 //向客户端发送聊天室名,并获取客户端连接名
89 ((DataOutputStream)m.get("out")).writeUTF("6666");
90 m.put("client",((DataInputStream)m.get("in")).readUTF());
91 System.out.printf("新人%s加入聊天室!\n",m.get("client"));
92
93 ins.add(m);
94 outs.add(m);
95 socket.add(m);
96
97 //发送群体上线通知
98 Map sv = new HashMap<>();
99 sv.put("client","server");
100 sv.put("str",m.get("client")+"加入聊天室!");
101 str.add(sv);
102 }
103 } catch (Exception e) {
104 e.printStackTrace();
105 }
106 }
107 }
Server
客户端代码:

1 package com.example.demo.socket;
2
3 import java.io.DataInputStream;
4 import java.io.DataOutputStream;
5 import java.io.IOException;
6 import java.net.Socket;
7 import java.util.Scanner;
8
9 public class Client {
10
11 public static void main(String[] args) {
12 //服务端 IP
13 String serverName = "localhost";
14 //服务端 端口号
15 int port = 6666;
16 try {
17 Socket client = new Socket(serverName,port);
18 DataInputStream in = new DataInputStream(client.getInputStream());
19 DataOutputStream out = new DataOutputStream(client.getOutputStream());
20 //向服务端发送连接名,并确认服务端收到连接名且返回聊天室名
21 out.writeUTF("client");
22 out.flush();
23 System.out.printf("进入聊天室 %s \n",in.readUTF());
24 try {
25 new Thread(new Runnable() {
26 @Override
27 public void run() {
28 try {
29 while (true) {
30 System.out.println(in.readUTF());
31 }
32 } catch (IOException e) {
33 e.printStackTrace();
34 }
35 }
36 }).start();
37 while (true) {
38 out.writeUTF(new Scanner(System.in).nextLine());
39 out.flush();
40 }
41 } finally {
42 client.close();
43 }
44 } catch (Exception e) {
45 e.printStackTrace();
46 }
47
48 }
49 }
Client
基于Socket实现多人聊天室的更多相关文章
- java socket之多人聊天室Demo
一.功能介绍 该功能实现了一个类似QQ的最简单多人聊天室,如下图所示. 二.目录结构 三.服务端 1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程: pa ...
- 多线程+socket实现多人聊天室
最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo: demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消 ...
- 基于swoole实现多人聊天室
核心的swoole代码 基本的cs(client-sercer)结构不变,这里利用的是redis的哈希和set来储存和分组;从而达到了分组,统计,定时推送等功能;最后利用onclose事件来剔除断开的 ...
- 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室
原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室
原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...
- 基于tcp和多线程的多人聊天室-C语言
之前在学习关于网络tcp和多线程的编程,学了知识以后不用一下总绝对心虚,于是就编写了一个基于tcp和多线程的多人聊天室. 具体的实现过程: 服务器端:绑定socket对象->设置监听数-> ...
- 多人聊天室(Java)
第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...
- Apache MiNa 实现多人聊天室
Apache MiNa 实现多人聊天室 开发环境: System:Windows JavaSDK:1.6 IDE:eclipse.MyEclipse 6.6 开发依赖库: Jdk1.4+.mina-c ...
- 基于LINUX的多功能聊天室
原文:基于LINUX的多功能聊天室 基于LINUX的多功能聊天室 其实这个项目在我电脑已经躺了多时,最初写完项目规划后,我就认认真真地去实现了它,后来拿着这个项目区参加了面试,同样面试官也拿这个项目来 ...
随机推荐
- 微服务探索之路01篇.net6.0项目本地win10系统docker到服务器liunx系统docker的贯通
本文介绍从创建 net6.0 项目运行在 windows 开发环境的 docker 然后正式部署至 liunx 服务器. 1 windows10 安装 docker 下载docker-desktop ...
- Linux中ssh登陆慢的两种原因
useDNS配置导致登陆慢 如果ssh server的配置文件(通常是 /etc/ssh/sshd_config )中设置 useDNS yes ,可能会导致 ssh 登陆卡住几十秒.将该配置项设为 ...
- 初识python 之 爬虫:爬取某电影网站信息
注:此代码仅用于个人爱好学习使用,不涉及任何商业行为! 话不多说,直接上代码: 1 #!/user/bin env python 2 # author:Simple-Sir 3 # time:201 ...
- CentOS7中安装pip的方法
1.安装epel-release [root@localhost ~]# yum -y install epel-release 2.安装python-pip [root@localhost ~]# ...
- SYCOJ2140祝福短信
题目-祝福短信 (shiyancang.cn) 1 #include<bits/stdc++.h> 2 using namespace std; 3 map<string,bool& ...
- grafana中如何展示prometheus的延迟分布数据?
最终效果 最终在grafana中展示了一个服务每分钟的延迟分布: 各个部分的含义如下: 1.时间的分布,从0.01秒到最多720秒 2.用颜色深浅代表次数.颜色越深,请求次数越多 3.时间轴,代表在这 ...
- JUC之文章整理以及汇总
JUC文章汇总 JUC部分将学习<JUC并发编程的艺术>和<尚硅谷-大厂必备技术之JUC并发编程>进行博客的整理,各文章中也会不断的完善和丰富. JUC概述 JUC的视频学习和 ...
- WebGPU | 相关知识概述
首先看下WebGPU的目标: 同时支持实时屏幕渲染和离屏渲染. 使通用计算能够在 GPU 上高效执行. 支持针对各种原生 GPU API 的实现:Microsoft 的 D3D12.Apple 的 M ...
- Go 变量及基本数据类型3
#### Go 变量及基本数据类型(三)今天学习一下剩下的两个基本数据类型(布尔类型,字符串类型)以及基本数据类型的相互转换##### 布尔类型布尔类型也称为bool 类型, bool 类型只允许取值 ...
- JavaScript之详述闭包导致的内存泄露
一.内存泄露 1. 定义:一块被分配的内存既不能使用,也不能回收.从而影响性能,甚至导致程序崩溃. 2. 起因:JavaScript的垃圾自动回收机制会按一定的策略找出那些不再继续使用的变量,释放其占 ...