服务器之家

服务器之家 > 正文

Java SE实现多人聊天室功能

时间:2021-07-01 13:50     来源/作者:L_X_Y_HH

本文实例为大家分享了java se实现多人聊天室功能的具体代码,供大家参考,具体内容如下

实现功能:

1.实现用户注册上线,下线

2.实现群聊和私聊功能

3.实现统计当前在线人数

实现思路:

1.首先,要实现服务端与客户端之间的连接

这里是使用套接字建立tcp连接:

(1)服务器端先实例化一个描述服务器端口号的serversocket对象

(2)客户端要创建socket对象来连接指定的服务器端

(3)服务器端调用serversocket类的accept()方法来监听连接到服务器端的客户端信息

(4)若服务器端与客户端连接成功,双方将返回一个socket对象,此时双方可以进行通信

(5)服务器端与客户端使用i/o流进行连接,服务端的输出流连接客户端的输入流,客户端的输出流连接服务端的输入流

(6)使用close()方法关闭套接字(一定要记得关闭)

2.因为是拥有一个服务端来实现多个客户端的连接,此处还要解决的是多线程的问题。

每个客户端需要两个线程,来分别处理向服务端发送消息和向服务端接收消息

而服务端,当每增加一个客户端与服务端连接,服务端都要多创建一个线程来处理与客户端的连接

具体代码:

单线程实现:

客户端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.ioexception;
import java.io.printstream;
import java.net.socket;
import java.util.scanner;
 
/**
 * @author lxy
 * @email 403824215@qq.com
 * @date 2018/7/20 15:46
 */
//客户端
public class singleclient {
  public static void main(string[] args) throws ioexception {
    //客户端连接服务器,返回套接字socket对象
    socket socket = new socket("127.0.0.1",6666);
    //获取服务端的输出流,向服务器端输出内容
    printstream printstream = new printstream(socket.getoutputstream());
    printstream.println("我是客户端" + socket.getlocalport());
    //获取服务器端的输入流,读取服务器端的内容
    scanner scanner = new scanner(socket.getinputstream());
    scanner.usedelimiter("\n");
    if(scanner.hasnext())
    {
      system.out.println(scanner.next());
    }
    //关闭流
    socket.close();
  }
}

服务端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.io.ioexception;
import java.io.printstream;
import java.net.serversocket;
import java.net.socket;
import java.util.scanner;
 
/**
 * @author lxy
 * @email 403824215@qq.com
 * @date 2018/7/20 15:34
 */
//服务端
public class singleserver {
  public static void main(string[] args) throws ioexception {
    //创建服务器端的serversocket对象,等待客户端进行连接
    serversocket serversocket = new serversocket(6666);
    system.out.println("服务器的端口号为6666,等待客户端连接。。。");
    //侦听并接收服务器端的连接,返回套接字socket对象
    socket socket = serversocket.accept();
    //获取客户端的输入流,读取客户端的输入内容
    scanner scanner = new scanner(socket.getinputstream());
    scanner.usedelimiter("\n");
    if(scanner.hasnext())
    {
      system.out.println("客户端发来消息:" + scanner.next());
    }
    //获取客户端的输出流,向客户端输出内容
    printstream printstream = new printstream(socket.getoutputstream());
    printstream.println("客户端你好,我是服务器端:" + serversocket.getlocalport());
    //关闭流
    serversocket.close();
  }
}

多线程实现

客户端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import java.io.ioexception;
import java.io.printstream;
import java.net.socket;
import java.util.scanner;
 
/**
 * @author lxy
 * @email 403824215@qq.com
 * @date 2018/7/20 15:55
 */
//客户端
 
//客户端读取服务器端信息的线程
class clientreadserver implements runnable
{
  private socket socket;
 
  public clientreadserver(socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      scanner scanner = new scanner(socket.getinputstream());
      while (scanner.hasnext())
      {
        system.out.println(scanner.next());
      }
      socket.close();
    } catch (ioexception e) {
      e.printstacktrace();
    }
  }
}
 
 
//客户端向服务端发送信息的线程
class clientsendserver implements runnable
{
  private socket socket;
 
  public clientsendserver(socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      printstream printstream = new printstream(socket.getoutputstream());
      scanner scanner = new scanner(system.in);
      while (true)
      {
        string msg = null;
        if(scanner.hasnext())
        {
          msg = scanner.next();
          printstream.println(msg);
        }
        if(msg.equals("bye"))
        {
          scanner.close();
          printstream.close();
          break;
        }
      }
    } catch (ioexception e) {
      e.printstacktrace();
    }
 
  }
}
 
public class multiclient {
  public static void main(string[] args) throws ioexception {
    socket socket = new socket("127.0.0.1",6666);
    thread read = new thread(new clientreadserver(socket));
    thread send = new thread(new clientsendserver(socket));
    read.start();
    send.start();
  }
}

服务端

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import java.io.ioexception;
import java.io.printstream;
import java.net.serversocket;
import java.net.socket;
import java.util.map;
import java.util.scanner;
import java.util.set;
import java.util.concurrent.concurrenthashmap;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;
import java.util.regex.matcher;
import java.util.regex.pattern;
 
/**
 * @author lxy
 * @email 403824215@qq.com
 * @date 2018/7/20 16:12
 */
class server implements runnable
{
  private static map<string,socket> map = new concurrenthashmap<string, socket>();
 
  private socket socket;
 
  public server(socket socket)
  {
    this.socket = socket;
  }
 
  public void run() {
    try {
      scanner scanner = new scanner(socket.getinputstream());
      string msg = null;
      while (true)
      {
        if(scanner.hasnextline())
        {
          msg = scanner.nextline();
          pattern pattern = pattern.compile("\r");
          matcher matcher = pattern.matcher(msg);
          msg = matcher.replaceall("");
          //用户注册——格式:username:用户名
          if(msg.startswith("username:"))
          {
            string username = msg.split("\\:")[1];
            userregist(username,socket);
            continue;
          }
          //群聊——格式:g:群聊信息
          else if(msg.startswith("g:"))
          {
            firststep(socket);
            string str = msg.split("\\:")[1];
            groupchat(socket,str);
            continue;
          }
          else if(msg.startswith("p:") && msg.contains("-"))
          {
            firststep(socket);
            string username = msg.split("\\:")[1].split("-")[0];
            string str = msg.split("\\:")[1].split("-")[1];
            privatechat(socket,username,str);
            continue;
          }
          else if(msg.contains("bye"))
          {
            firststep(socket);
            userexit(socket);
            continue;
          }
          else
          {
            printstream printstream = new printstream(socket.getoutputstream());
            printstream.println("格式输入错误");
            continue;
 
          }
        }
      }
    } catch (ioexception e) {
      e.printstacktrace();
    }
 
  }
 
  private void firststep(socket socket) throws ioexception {
    set<map.entry<string,socket>> set = map.entryset();
    for(map.entry<string,socket> entry:set)
    {
      if(entry.getvalue().equals(socket))
      {
        if(entry.getvalue() == null)
        {
          printstream printstream = new printstream(socket.getoutputstream());
          printstream.println("请先进行注册操作!格式为:[username:用户名]");
        }
      }
    }
  }
 
  private void userregist(string username, socket socket) {
    map.put(username,socket);
    system.out.println("用户名:" + username + "客户端" + socket +"上线了!!");
    system.out.println("当前在线人数为" + map.size() + "人");
  }
 
  private void groupchat(socket socket, string msg) throws ioexception {
    set<map.entry<string,socket>> set = map.entryset();
    string username = null;
    for(map.entry<string,socket> entry:set)
    {
      if(entry.getvalue().equals(socket))
      {
        username = entry.getkey();
        break;
      }
    }
    for(map.entry<string,socket> entry:set)
    {
      socket client = entry.getvalue();
      printstream printstream = new printstream(client.getoutputstream());
      printstream.println(username + "说" + msg);
    }
  }
 
  private void privatechat(socket socket, string username, string msg) throws ioexception {
    string curuser = null;
    set<map.entry<string,socket>> set = map.entryset();
    for(map.entry<string,socket> entry:set)
    {
      if(entry.getvalue().equals(socket))
      {
        curuser = entry.getkey();
        break;
      }
    }
    socket client = map.get(username);
    printstream printstream = new printstream(client.getoutputstream());
    printstream.println(curuser + "私聊说" + msg);
  }
 
  private void userexit(socket socket) {
    string username = null;
    for(string key:map.keyset())
    {
      if(map.get(key).equals(socket))
      {
        username = key;
        break;
      }
    }
    map.remove(username,socket);
    system.out.println("用户" + username + "已下线");
  }
}
 
 
public class multiserver {
  public static void main(string[] args) {
    try {
      serversocket serversocket = new serversocket(6666);
      //使用线程池
      executorservice executorservice = executors.newfixedthreadpool(20);
      for(int i = 0;i < 20;i++)
      {
        system.out.println("欢迎来到聊天室。。。");
        socket socket = serversocket.accept();
        system.out.println("新人加入。。。");
        executorservice.execute(new server(socket));
      }
      executorservice.shutdown();
      serversocket.close();
    } catch (ioexception e) {
      e.printstacktrace();
    }
 
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/L_X_Y_HH/article/details/80633819

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部