Java多线程实现多人聊天室功能

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

1.实验目的:

编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是 “欢迎使用 XXX 聊天室应用”,其中 XXX 是自己的班级姓名学号,如“软件 171 张三 1234”。

2.实验代码:

服务端程序代码:

ServerChar.java

package works;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class ServerChat {

 //定义Map集合用于存储用户的Socket以及用户的名字   key:Socket    Value:用户名
 public final static Map<Socket,String> socketsMaps = Collections.synchronizedMap(new HashMap<Socket,String>());
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try {
   // 创建服务端套接字
   ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("------服务端暴露-------");
   while (true) {
    // 监听客户端套接字,若有客户端连接,则代码不会往下执行,否则会堵塞在此处。
    Socket socket = serverSocket.accept();

    // 开启线程,用于读取客户端发送的信息,并转发给每一个客户端
    new ThreadServer(socket).start();
   }
  } catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }
 }
}

class ThreadServer extends Thread {
 private Socket socket;
 ThreadServer(){};
 ThreadServer(Socket socket)
 {
  this.socket = socket;
 }
 @Override
 public void run() {
  try {
   while(true)
   {
    DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
    String data = dataInputStream.readUTF();

    if(data.startsWith("①②③④")&&data.endsWith("①②③④"))
    {
     //发送过来的是用户名
     //将Socket以及用户名字都存放在Map集合中
     ServerChat.socketsMaps.put(socket, data.replace("①②③④",""));
     //获取所有的key(Socket),将所有用户的名字发送至客户端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //获取所有的用户的名字,将这些名字拼装成一个字符串
     Collection<String> names = ServerChat.socketsMaps.values();
     StringBuffer sbf = new StringBuffer();
     for(String userName :names)
     {
      sbf.append(userName).append(",");
     }
     System.out.println("sbf:"+sbf.toString());
     for(Socket soc:sockets)
     {
      DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream());
      dataOutputStream.writeUTF("①②③④"+sbf.toString()+"①②③④");
      dataOutputStream.flush();
     }
    }
    else{
     //发送过来的是聊天信息
     //获取所有的key(Socket),将所有用户的名字发送至客户端
     Set<Socket> sockets = ServerChat.socketsMaps.keySet();
     //將聊天信息广播出去
     for(Socket soc:sockets)
     {
      DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream());
      dataOutputStream.writeUTF("[ "+ServerChat.socketsMaps.get(socket)+" ]说:"+data);
      dataOutputStream.flush();
     }

    }

   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
}

客户端程序代码:

ClientChar.java

package works;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class ClientChat {

 private JFrame mainWin = new JFrame("聊天窗口");

 // 消息展示框
 private JTextArea displayTa = new JTextArea(14, 40);
 // 在线用户名称展示框
 private DefaultListModel<String> userListModel = new DefaultListModel<>();
 private JList<String> userList = new JList<>(userListModel);
 // 消息发送框
 private JTextArea inputTF = new JTextArea(4, 40);
 // 消息按钮
 private JButton sendBn = new JButton("发送");
 // 用户记录当前聊天用户名
 private String curUser;

 public static void main(String[] args) {
  new ClientChat().init();
 }

 private void init() {
  try {
   // 通过弹出对话框获取用户输入的用户名
   String userName = JOptionPane.showInputDialog(mainWin, "请输入您的用户名:");
   // 把用户输入的用户名,赋给curUser
   curUser = userName;
   mainWin.setTitle(curUser + "的聊天窗口");

   // 创建套接字
   Socket socket = new Socket("192.168.193.1", 9999);
   // 向服务器声明
   DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
   //发送用户名到服务端
   dataOutputStream.writeUTF("①②③④"+userName+"①②③④");
   dataOutputStream.flush();

   // 开启线程,用于读取服务器发送的信息
   new ThreadClient(socket, this).start();

   JPanel bottomPanel = new JPanel();

   // 将消息框和按钮添加到窗口的底端
   mainWin.add(bottomPanel, BorderLayout.SOUTH);
   bottomPanel.add(inputTF);
   bottomPanel.add(sendBn);

   ActionListener listener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
     // 获取用户发送的消息
     String message = inputTF.getText();
     sendSms(message,socket);
    }
   };
   // 给发送消息按钮绑定点击事件监听器
   sendBn.addActionListener(listener);

   JPanel centerPanel = new JPanel();

   // 将展示消息区centerPanel添加到窗口的中间
   mainWin.add(centerPanel);
   // 让展示消息区可以滚动
   centerPanel.add(new JScrollPane(displayTa));
   displayTa.setEditable(false);
   // 用户列表和是否私聊放到窗口的最右边
   Box rightBox = new Box(BoxLayout.Y_AXIS);
   userList.setFixedCellWidth(60);
   userList.setVisibleRowCount(13);
   rightBox.add(new JLabel("用户列表:"));
   rightBox.add(new JScrollPane(userList));

   centerPanel.add(rightBox);

   // 关闭窗口退出当前程序
   mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   mainWin.pack(); // swing加上这句就可以拥有关闭窗口的功能
   mainWin.setVisible(true);

  } catch (Exception e) {
   // TODO: handle exception
   e.printStackTrace();
  }
 }
  //点击发送后将消息发送到服务器
  protected void sendSms(String sms, Socket socket) {
   try {
    //发送聊天消息到服务端
    DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
    dataOutputStream.writeUTF(sms);
    dataOutputStream.flush(); 

   } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
   }
  }

  public DefaultListModel<String> getUserListModel() {
   return userListModel;
  }

  public JTextArea getDisplayTa() {
   return displayTa;
  }
  public JTextArea getInputTF()
  {
   return inputTF;
  }
}

// 定义线程类,用来读取服务器发送的信息
class ThreadClient extends Thread {
 private Socket socket;
 private ClientChat clientChat;

 ThreadClient() {
 }

 ThreadClient(Socket socket, ClientChat clientChat) {
  this.socket = socket;
  this.clientChat = clientChat;
 }

 @Override
 public void run() {

  try {
   while (true) {
    DataInputStream DataInputStream = new DataInputStream(socket.getInputStream());
    String message = DataInputStream.readUTF();

    if(message.startsWith("①②③④")&&message.endsWith("①②③④"))
    {
     //说明信息是用户名
     String[] names = message.replace("①②③④","").split(",");
     // 将用户列表先清空
     clientChat.getUserListModel().clear();
     for (int i = 0; i < names.length; ++i) {
      clientChat.getUserListModel().addElement(names[i]);
     }
    }
    else
    {
     //说明是聊天信息,将聊天信息放在displayTa中
     clientChat.getInputTF().setText("");
     clientChat.getDisplayTa().append(message+"\t\n");
    }

   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
}

3.实验截图

先开启服务端

再开启客户端

聊天过程

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

(0)

相关推荐

  • 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

  • java socket实现聊天室 java实现多人聊天功能

    用java socket做一个聊天室,实现多人聊天的功能.看了极客学院的视频后跟着敲的.(1DAY) 服务端: 1. 先写服务端的类MyServerSocket,里面放一个监听线程,一启动就好 2. 实现服务端监听类ServerListener.java,用accept来监听,一旦有客户端连上,生成新的socket,就新建个线程实例ChatSocket.启动线程后就把线程交给ChatManager管理 3. 在ChatSocket中实现从客户端读取内容,把读取到的内容发给集合内所有的客户端 4.

  • 使用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实现简易聊天室实例

    本文实例讲述了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编写局域网多人聊天室

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

  • java聊天室的实现代码

    本文实例为大家分享了java实现聊天室的具体代码,供大家参考,具体内容如下 聊天室界面: 源码: public class ClientFrame extends Frame { private TextField textFieldContent = new TextField(); private TextArea textAreaContent = new TextArea(); private Socket socket = null; private OutputStream out

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

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

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

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

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

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

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

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

随机推荐