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();
    }

  }
}

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

时间: 2019-01-09

基于java编写局域网多人聊天室

由于需要制作网络计算机网络课程设计,并且不想搞网络布线或者局域网路由器配置等等这种完全搞不懂的东西,最后决定使用socket基于java编写一个局域网聊天室: 关于socket以及网络编程的相关知识详见我另一篇文章:Java基于socket编程 程序基于C/S结构,即客户端服务器模式. 服务器: 默认ip为本机ip 需要双方确定一个端口号 可设置最大连接人数 可启动与关闭 界面显示在线用户人以及姓名(本机不在此显示) 客户端: 需要手动设置服务器ip地址(局域网) 手动设置端口号 输入姓名 可连

使用Java和WebSocket实现网页聊天室实例代码

在没介绍正文之前,先给大家介绍下websocket的背景和原理: 背景 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可以预见,如果websocket一旦在浏览器中得到实现,将会替代上面两项技术,得到广泛的使用.面对这种状况,HTML5定义了WebSocket协议,能更

Java基于socket实现简易聊天室实例

本文实例讲述了Java基于socket实现简易聊天室的方法.分享给大家供大家参考.具体实现方法如下: chatroomdemo.java package com.socket.demo; import java.io.IOException; import java.net.DatagramSocket; public class ChatRoomDemo { /** * @param args * @throws IOException */ public static void main(S

java基于C/S结构实现多线程聊天室

本文实例为大家分享了java基于C/S结构实现多线程聊天室的具体代码,供大家参考,具体内容如下 主要实现的功能: 服务器端建立ServerSocket阻塞监听来自客户端的Socket连接,并为之开辟一个新的线程 读取来自该连接的数据,广播每一个客户端数据,这里简单地使用一个链表保存所有来自客户端的所有Socket连接 客户端连接上服务器端后主要有两个线程在工作: 主线程:不断获取键盘的输入并写入该Socket中传输给服务器 副线程:不断从服务器Socket流中读取传来的数据,打印到屏幕上. 服务

Java Socket聊天室编程(一)之利用socket实现聊天之消息推送

相关阅读:Java Socket聊天室编程(二)之利用socket实现单聊聊天室 网上已经有很多利用socket实现聊天的例子了,但是我看过很多,多多少有一些问题存在. 这里我将实现一个比较完整的聊天例子,并解释其中的逻辑. 由于socket这一块比较大,所以我将分出几篇来写一个比较完整的socket例子. 这里我们先来实现一个最简单的,服务器与客户端通讯,实现消息推送的功能. 目的:服务器与客户端建立连接,客户端可以向服务器发送消息,服务器可以向客户端推送消息. 1,使用java建立socke

java+jdbc+mysql+socket搭建局域网聊天室

本文实现思路:利用UDP协议进行局域网信息传输,建立点对点的聊天网络,每个端用户有自己的一个mysql数据库,所以需要获取其数据库用户名和密码,然后通过该数据库内容发送信息,接收消息则没有限制, 步骤: 建立数据表存储主机ip,接收信息端口port,nickname 向所有用户发送信息 接收信息 小部件(添加好友,删除好友) 一.建立数据表存储主机ip,接收信息端口port,nickname 在mysql数据库里建立chatusr数据表,表的格式为: 检测表是否存在和建立数据表的代码如下: vo

使用java基于pushlet和bootstrap实现的简单聊天室

这是一个简单的不能再简单的聊天室,本代码包含以下功能 1.用户注册. 2.用户登录. 3.当然还可以聊天. DBUtil.java 复制代码 代码如下: package com.hongyuan.core;   import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statemen

Java Socket聊天室编程(二)之利用socket实现单聊聊天室

在上篇文章Java Socket聊天室编程(一)之利用socket实现聊天之消息推送中我们讲到如何使用socket让服务器和客户端之间传递消息,达到推送消息的目的,接下来我将写出如何让服务器建立客户端与客户端之间的通讯. 其实就是建立一个一对一的聊天通讯. 与上一篇实现消息推送的代码有些不同,在它上面加以修改的. 如果没有提到的方法或者类则和上一篇一模一样. 1,修改实体类(服务器端和客户端的实体类是一样的) 1,UserInfoBean 用户信息表 public class UserInfoB

java使用MulticastSocket实现基于广播的多人聊天室

使用MulticastSocket实现多点广播: (1)DatagramSocket只允许数据报发给指定的目标地址,而MulticastSocket可以将数据报以广播的方式发送到多个客户端. (2)IP协议为多点广播提供了这批特殊的IP地址,这些IP地址的范围是:224.0.0.0至239.255.255.255.. (3)MulticastSocket类时实现多点广播的关键,当MulticastSocket把一个DaragramPocket发送到多点广播的IP地址时,该数据报将会自动广播到加入

java实现一个简单TCPSocket聊天室功能分享

本文实例为大家分享了java实现TCPSocket聊天室功能的相关代码,供大家参考,具体内容如下 1.TCPserver.java import java.net.*; import java.io.*; import java.util.*; import java.util.concurrent.*; public class TCPserver{ private static final int SERVERPORT = 8888; private ServerSocket MyServe

nodejs实现的一个简单聊天室功能分享

今天我来实现一个简单的聊天室,后台用nodejs, 客户端与服务端通信用socket.io,这是一个比较成熟的websocket框架. 初始工作 1.安装express, 用这个来托管socket.io,以及静态页面,命令npm install express --save,--save可以使包添加到package.json文件里. 2.安装socket.io,命令npm install socket.io --save. 编写服务端代码 首先我们通过express来托管网站,并附加到socke

ASP建立一个简单的聊天室

经过一个阶段的asp学习,下面我们结合所学过的内容建立一个最简单的聊天室,虽然很简单,但是大家可以通过它来掌握一个聊天室建立的基本过程,并且可以不断的完善其功能. 下面介绍其主要步骤: 1,添加Global.asa文件里面的代码.这部分代码主要处理Application_onStart事件,在此事件中,定义了一个有15个元素的数据,并把它赋给了一个Application对象的属性.Global.asa文件的内容如下. <SCRIPT LANGUAGE="VBScript" RUN

java编程实现多人聊天室功能

本文实例为大家分享了java实现多人聊天室的具体代码,供大家参考,具体内容如下 程序源代码及运行截图: server.java //server.java package Socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; impor

js编写简单的聊天室功能

这个聊天室写的特别简易,比较适合刚开始学习js的同学借鉴,当然,写的不好,也希望诸位大神可以进行批评改正. 聊天室要求: 1.不能发空消息 2.敏感字***显示 3.图片替换 开心,尴尬 4.显示聊天内容和时间 5.每发一条信息,随机显示名称,先把一些名称定义到array里面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> &

Android编写简单的聊天室应用

最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能.主要技术点就是怎样把表情图片放到textview等Ui控件中展示.这里废话不多说,下面是效果图: 这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录drawable中而所有的资源文件都是R这个类来管理,所以我们可以利用正则表达式找出图片id包装成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源码: pack

用PHP+MySQL搭建聊天室功能实例代码

下面,以一个简单的聊天室设计为例,介绍PHP+MySQL在网页开发中的应用 1.总体设计 1.1 构思与规划: 聊天室的基本原理,就是把每个连上同一网页的用户传送的发言数据储存起来,然后将所有的发言数据传给每一用户.也就是说,用数据库汇集每个人的发言,并将数据库中的数据传给每一个人就实现了聊天室的功能. 1.2 表设计 首先使用MySQL建立表chat用来储存用户的发言: 复制代码 代码如下: mysql> CREATE TABLE chat -> (chtime DATATIME, ->

Python实现基于C/S架构的聊天室功能详解

本文实例讲述了Python实现基于C/S架构的聊天室功能.分享给大家供大家参考,具体如下: 一.课程介绍 1.简介 本次项目课是实现简单聊天室程序的服务器端和客户端. 2.知识点 服务器端涉及到asyncore.asynchat和socket这几个模块,客户端用到了telnetlib.wx.time和thread这几个模块. 3.所需环境 本次课中编写客户端需要用到wxPython,它是一个GUI工具包,请先使用下面的命令安装: $ sudo apt-get install python-wxt

Java基于UDP协议实现简单的聊天室程序

最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. 先看一下效果: 实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理.  "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着. 看一下代码实现: 1.首先是消息服务器的实现,功能很简单: •将客户端的信息(进入了哪一