ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于Socket实现多人聊天室

2021-05-10 18:04:26  阅读:189  来源: 互联网

标签:聊天室 java Socket get client 多人 import new out


当前支持:

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

 

标签:聊天室,java,Socket,get,client,多人,import,new,out
来源: https://www.cnblogs.com/tangzeqi/p/14752041.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有