基于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的多功能聊天室 其实这个项目在我电脑已经躺了多时,最初写完项目规划后,我就认认真真地去实现了它,后来拿着这个项目区参加了面试,同样面试官也拿这个项目来 ...
随机推荐
- 新环境chart包helmlint校验
在iot目录内可以执行helm lint iot-api 去校验
- nodejs创建一个简单的web服务
这是一个突如其来的想法,毕竟做web服务的框架那么多,为什么要选择nodejs,因为玩前端时,偶尔想调用接口获取数据,而不想关注业务逻辑,只是想获取数据,使用java或者.net每次修改更新后还要打包 ...
- JS 在使用hasOwnProperty()函数时报错
在使用hasOwnProperty()方法判断对象是否具有某种属性时eslint报下列错误: Do not access Object.prototype method 'hasOwnProperty ...
- Linux下校验SHA1和MD5的方法
当我们从互联网下载东西或者从U盘拷贝东西的时候,通常是不会和源文件有什么区别的,但是在偶然的情况下会出现下载或者拷贝出错的情况, 尤其是在下载大文件的时候,比如系统光盘......当你装机到一半才发现 ...
- spring boot + redis --- 心得
1.前言 习惯使用springMVC 配置 redis ,现在使用spring boot ,得好好总结怎么在spring boot 配置和使用 ,区别真的挺大的. 2.环境 spring boot ...
- ON UPDATE CURRENT_TIMESTAMP请慎用
大家好,我是架构摆渡人.这是实践经验系列的第七篇文章,这个系列会给大家分享很多在实际工作中有用的经验,如果有收获,还请分享给更多的朋友. 今天给大家分享一个容易忽略的问题,正是因为容易忽略,所以才要重 ...
- 网络编程-跨域资源共享 CORS
目录 1.什么是同源策略? 2.跨域资源共享 CORS 3.预检请求 4.CORS相关字段 5.Golang实现跨域 6.参考资料 1.什么是同源策略? 如果两个 URL 的 protocol.por ...
- 走进Task(1):什么是Task
目录 前言 从表象讲起 Task 从何而来 Task 常见用法 Task 的分类 按是否包含 Result 分,也就是是否是泛型 Task 按得到 Task 的方式,可以分为 对 Task 进行分解 ...
- eclipse不能创建web项目,如何设置(亲测可用)
具体描述:就是在项目右键或者file-->new的时候没有dynamic web project选项)(我这里已经解决.所以看得到) 根本原因:就是有没有web的开发插件 两种办法 1.下载使用 ...
- Qt之QFontDialog
widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> class Widget : public QWidget { ...