首页 > 编程 > Java > 正文

Java SE实现多人聊天室功能

2019-11-26 09:21:27
字体:
来源:转载
供稿:网友

本文实例为大家分享了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();    }   }}

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表