评论

收藏

[Java] Java SE实现多人聊天室功能

编程语言 编程语言 发布于:2021-10-05 22:35 | 阅读数:426 | 评论:0

这篇文章主要为大家详细介绍了Java SE实现多人聊天室功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了java se实现多人聊天室功能的具体代码,供大家参考,具体内容如下
实现功能:
1.实现用户注册上线,下线
2.实现群聊和私聊功能
3.实现统计当前在线人数
实现思路:
1.首先,要实现服务端与客户端之间的连接
这里是使用套接字建立tcp连接:
(1)服务器端先实例化一个描述服务器端口号的serversocket对象
(2)客户端要创建socket对象来连接指定的服务器端
(3)服务器端调用serversocket类的accept()方法来监听连接到服务器端的客户端信息
(4)若服务器端与客户端连接成功,双方将返回一个socket对象,此时双方可以进行通信
(5)服务器端与客户端使用i/o流进行连接,服务端的输出流连接客户端的输入流,客户端的输出流连接服务端的输入流
(6)使用close()方法关闭套接字(一定要记得关闭)
2.因为是拥有一个服务端来实现多个客户端的连接,此处还要解决的是多线程的问题。
每个客户端需要两个线程,来分别处理向服务端发送消息和向服务端接收消息
而服务端,当每增加一个客户端与服务端连接,服务端都要多创建一个线程来处理与客户端的连接
具体代码:
单线程实现:
客户端
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();
  }
}
服务端
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();
  }
}
多线程实现
客户端
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();
  }
}
服务端
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();
  }
 
  }
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家
原文链接:https://blog.csdn.net/L_X_Y_HH/article/details/80633819

关注下面的标签,发现更多相似文章