热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

java局域网聊天小程序

这篇文章主要为大家详细介绍了java局域网聊天小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了java局域网聊天程序的具体代码,供大家参考,具体内容如下

有服务器端 和客户端两个界面,运行需要加上自己的ip地址,端口可以随意,但是客户端端口,和服务器端口要一样,然后就可以几个人一块聊天了

简单贴几个代码吧  

Client.java  客户端代码

package chat;
 
import java.awt.BorderLayout;//布置容器的边框布局
import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;//布局处理器
import java.awt.Toolkit;//抽象超类
import java.awt.event.ActionEvent;//指示发生了组件定义的动作的语义事件
import java.awt.event.ActionListener;//用于接收操作事件的侦听器接口
import java.awt.event.MouseEvent;//指示组件中发生鼠标动作的事件
import java.awt.event.MouseListener;//鼠标事件的侦听器接口
import java.awt.event.WindowAdapter;//接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象
import java.awt.event.WindowEvent;//指示窗口状态改变的低级别事件
import java.io.BufferedReader;//提供通用的缓冲方式文本读取
import java.io.IOException;//输入输出异常
import java.io.InputStreamReader;//字节流通向字符流的桥梁
import java.io.PrintWriter;//向文本输出流打印对象的格式化表示形式
import java.net.Socket;//套接字,网络上的两个程序通过一个双向的通信连接实现数据交换的通信
import java.util.HashMap;// HashMap 是 Map 接口的常用实现类
import java.util.Map;//存数据,将键映射到值的对象
import java.util.StringTokenizer;//允许应用程序将字符串分解为标记
 
import javax.swing.BorderFactory;//创建一个浮雕式的边框
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.JSplitPane;//分隔
import javax.swing.JTextArea;//多行文本
import javax.swing.JTextField;//文本
import javax.swing.border.EmptyBorder;//一个占用空间但不执行绘制的空透明边框
import javax.swing.border.TitledBorder;//该类实现在指定位置以指定对齐方式显示字符串标题的任意边框
 
import oldchat.ChatFrame;
 
 
public class Client
{
 
 private JFrame frame;
 private JList userList;
 private JTextArea textArea;
 private JTextField textField;
 private JTextField txt_port;
 private JTextField txt_hostIp;
 private JTextField txt_name;
 private JButton btn_start;
 private JButton btn_stop;
 private JButton btn_send;
 private JPanel northPanel;
 private JPanel southPanel;
 private JScrollPane rightScroll;
 private JScrollPane leftScroll;
 private JSplitPane centerSplit;
 
 private DefaultListModel listModel;
 private boolean isCOnnected= false;
 
 private Socket socket;//创建套接字
 private PrintWriter writer;
 private BufferedReader reader;
 private MessageThread messageThread;// 负责接收消息的线程
 private Map OnLineUsers= new HashMap();// 所有在线用户
 
 // 主方法,程序入口
 public static void main(String[] args) 
 {
 new Client();
 }
 
 // 执行发送
 public void send() 
 {
 if (!isConnected) 
 {
  JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",
   JOptionPane.ERROR_MESSAGE);
  return;
 }
 String message = textField.getText().trim();
 if (message == null || message.equals("")) 
 {
  JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",
   JOptionPane.ERROR_MESSAGE);
  return;
 }
 sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message);
 textField.setText(null);
 }
 
 // 构造方法
 public Client() 
 {
 textArea = new JTextArea();
 textArea.setEditable(false);
 textArea.setForeground(Color.blue);
 textField = new JTextField();
 txt_port = new JTextField("6666");
 txt_hostIp = new JTextField();
 txt_name = new JTextField();
 btn_start = new JButton("连接");
 btn_stop = new JButton("断开");
 btn_send = new JButton("发送");
 listModel = new DefaultListModel();
 userList = new JList(listModel);
 
 northPanel = new JPanel();
 northPanel.setLayout(new GridLayout(1, 7));
 northPanel.add(new JLabel("端口"));
 northPanel.add(txt_port);
 northPanel.add(new JLabel("服务器IP"));
 northPanel.add(txt_hostIp);
 northPanel.add(new JLabel("姓名"));
 northPanel.add(txt_name);
 northPanel.add(btn_start);
 northPanel.add(btn_stop);
 northPanel.setBorder(new TitledBorder("连接信息"));
 
 rightScroll = new JScrollPane(textArea);
 rightScroll.setBorder(new TitledBorder("群聊消息显示区"));
 leftScroll = new JScrollPane(userList);
 leftScroll.setBorder(new TitledBorder("在线用户(双击私聊)"));
 southPanel = new JPanel(new BorderLayout());
 southPanel.add(textField, "Center");
 southPanel.add(btn_send, "East");
 southPanel.setBorder(new TitledBorder("写消息"));
 
 centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,
  rightScroll);
 centerSplit.setDividerLocation(100);
 
 frame = new JFrame("客户端");
 // 更改JFrame的图标:
 //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.jpg")));
 frame.setLayout(new BorderLayout());
 frame.add(northPanel, "North");
 frame.add(centerSplit, "Center");
 frame.add(southPanel, "South");
 frame.setSize(600, 400);
 int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 frame.setLocation((screen_width - frame.getWidth()) / 2,
  (screen_height - frame.getHeight()) / 2);
 frame.setVisible(true);
 
 // 写消息的文本框中按回车键时事件
 textField.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent arg0) 
  {
  send();
  }
 });
 
 // 单击发送按钮时事件
 btn_send.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  send();
  }
 });
 
 // 单击连接按钮时事件
 btn_start.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  int port;
  if (isConnected) {
   JOptionPane.showMessageDialog(frame, "已处于连接上状态,不要重复连接!",
    "错误", JOptionPane.ERROR_MESSAGE);
   return;
  }
  try {
   try {
   port = Integer.parseInt(txt_port.getText().trim());
   } catch (NumberFormatException e2) {
   throw new Exception("端口号不符合要求!端口为整数!");
   }
   String hostIp = txt_hostIp.getText().trim();
   String name = txt_name.getText().trim();
   if (name.equals("") || hostIp.equals("")) {
   throw new Exception("姓名、服务器IP不能为空!");
   }
   boolean flag = connectServer(port, hostIp, name);
   if (flag == false) {
   throw new Exception("与服务器连接失败!");
   }
   frame.setTitle(name);
   JOptionPane.showMessageDialog(frame, "成功连接!");
  } catch (Exception exc) {
   JOptionPane.showMessageDialog(frame, exc.getMessage(),
    "错误", JOptionPane.ERROR_MESSAGE);
  }
  }
 });
//双击聊天(私聊) 
 userList.addMouseListener(new MouseListener() 
 {
  
  public void mouseReleased(MouseEvent e) {}
  public void mousePressed(MouseEvent e) {}
  public void mouseExited(MouseEvent e) {}
  public void mouseEntered(MouseEvent e) {}
  public void mouseClicked(MouseEvent e) 
  {
  if(e.getClickCount()==2) 
  {
   User user=onLineUsers.get(userList.getSelectedValue());
    ChatFrame.main(user.getIp());;
  } 
  }
 });
 
 // 单击断开按钮时事件
 btn_stop.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  if (!isConnected) {
   JOptionPane.showMessageDialog(frame, "已处于断开状态,不要重复断开!",
    "错误", JOptionPane.ERROR_MESSAGE);
   return;
  }
  try {
   boolean flag = closeConnection();// 断开连接
   if (flag == false) {
   throw new Exception("断开连接发生异常!");
   }
   JOptionPane.showMessageDialog(frame, "成功断开!");
  } catch (Exception exc) {
   JOptionPane.showMessageDialog(frame, exc.getMessage(),
    "错误", JOptionPane.ERROR_MESSAGE);
  }
  }
 });
 
 // 关闭窗口时事件
 frame.addWindowListener(new WindowAdapter() 
 {
  public void windowClosing(WindowEvent e) 
  {
  if (isConnected) {
   closeConnection();// 关闭连接
  }
  System.exit(0);// 退出程序
  }
 });
 }
 
 /**
 * 连接服务器
 * 
 * @param port
 * @param hostIp
 * @param name
 */
 public boolean connectServer(int port, String hostIp, String name) 
 {
 // 连接服务器
 try {
  socket = new Socket(hostIp, port);// 根据端口号和服务器ip建立连接
  writer = new PrintWriter(socket.getOutputStream());
  reader = new BufferedReader(new InputStreamReader(socket
   .getInputStream()));
  // 发送客户端用户基本信息(用户名和ip地址)
  sendMessage(name + "@" + socket.getLocalAddress().toString());
  // 开启接收消息的线程
  messageThread = new MessageThread(reader, textArea);
  messageThread.start();
  isCOnnected= true;// 已经连接上了
  return true;
 } catch (Exception e) {
  textArea.append("与端口号为:" + port + "  IP地址为:" + hostIp
   + "  的服务器连接失败!" + "\r\n");
  isCOnnected= false;// 未连接上
  return false;
 }
 }
 
 /**
 * 发送消息
 * 
 * @param message
 */
 public void sendMessage(String message) 
 {
 writer.println(message);
 writer.flush();
 }
 
 /**
 * 客户端主动关闭连接
 */
 @SuppressWarnings("deprecation")
 public synchronized boolean closeConnection() 
 {
 try {
  sendMessage("CLOSE");// 发送断开连接命令给服务器
  messageThread.stop();// 停止接受消息线程
  // 释放资源
  if (reader != null) {
  reader.close();
  }
  if (writer != null) {
  writer.close();
  }
  if (socket != null) {
  socket.close();
  }
  isCOnnected= false;
  return true;
 } catch (IOException e1) {
  e1.printStackTrace();
  isCOnnected= true;
  return false;
 }
 }
 
 // 不断接收消息的线程
 class MessageThread extends Thread {
 private BufferedReader reader;
 private JTextArea textArea;
 
 // 接收消息线程的构造方法
 public MessageThread(BufferedReader reader, JTextArea textArea) 
 {
  this.reader = reader;
  this.textArea = textArea;
 }
 
 // 被动的关闭连接
 public synchronized void closeCon() throws Exception 
 {
  // 清空用户列表
  listModel.removeAllElements();
  // 被动的关闭连接释放资源
  if (reader != null) {
  reader.close();
  }
  if (writer != null) {
  writer.close();
  }
  if (socket != null) {
  socket.close();
  }
  isCOnnected= false;// 修改状态为断开
 }
 
 public void run() {
  String message = "";
  while (true) {
  try {
   message = reader.readLine();
   StringTokenizer stringTokenizer = new StringTokenizer(message, "/@");
   String command = stringTokenizer.nextToken();// 命令
   if (command.equals("CLOSE"))// 服务器已关闭命令
   {
   textArea.append("服务器已关闭!\r\n");
   closeCon();// 被动的关闭连接
   return;// 结束线程
   } else if (command.equals("ADD")) {// 有用户上线更新在线列表
   String username = "";
   String userIp = "";
   if ((username = stringTokenizer.nextToken()) != null
    && (userIp = stringTokenizer.nextToken()) != null) 
   {
    User user = new User(username, userIp);
    onLineUsers.put(username, user);
    listModel.addElement(username);
   }
   } else if (command.equals("DELETE")) {// 有用户下线更新在线列表
   String username = stringTokenizer.nextToken();
   User user = (User) onLineUsers.get(username);
   onLineUsers.remove(user);
   listModel.removeElement(username);
   } else if (command.equals("USERLIST")) {// 加载在线用户列表
   int size = Integer
    .parseInt(stringTokenizer.nextToken());
   String username = null;
   String userIp = null;
   for (int i = 0; i 

Server.java

package chat;
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.StringTokenizer;
 
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.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
 
public class Server 
{
 
 private JFrame frame;
 private JTextArea contentArea;
 private JTextField txt_message;
 private JTextField txt_max;
 private JTextField txt_port;
 private JButton btn_start;
 private JButton btn_stop;
 private JButton btn_send;
 private JPanel northPanel;
 private JPanel southPanel;
 private JScrollPane rightPanel;
 private JScrollPane leftPanel;
 private JSplitPane centerSplit;
 private JList userList;
 private DefaultListModel listModel;
 
 private ServerSocket serverSocket;
 private ServerThread serverThread;
 private ArrayList clients;
 
 private boolean isStart = false;
 
 // 主方法,程序执行入口
 public static void main(String[] args) 
 {
 new Server();
 }
 
 // 执行消息发送
 public void send() 
 {
 if (!isStart) 
 {
  JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",
   JOptionPane.ERROR_MESSAGE);
  return;
 }
 if (clients.size() == 0) 
 {
  JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",
   JOptionPane.ERROR_MESSAGE);
  return;
 }
 String message = txt_message.getText().trim();
 if (message == null || message.equals("")) 
 {
  JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",
   JOptionPane.ERROR_MESSAGE);
  return;
 }
 sendServerMessage(message);// 群发服务器消息
 contentArea.append("服务器说:" + txt_message.getText() + "\r\n");
 txt_message.setText(null);
 }
 
 // 构造放法
 public Server() 
 {
 frame = new JFrame("服务器");
 // 更改JFrame的图标:
 //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));
 //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.jpg")));
 cOntentArea= new JTextArea();
 contentArea.setEditable(false);
 contentArea.setForeground(Color.blue);
 txt_message = new JTextField();
 txt_max = new JTextField("30");
 txt_port = new JTextField("6666");
 btn_start = new JButton("启动");
 btn_stop = new JButton("停止");
 btn_send = new JButton("发送");
 btn_stop.setEnabled(false);
 listModel = new DefaultListModel();
 userList = new JList(listModel);
 
 southPanel = new JPanel(new BorderLayout());
 southPanel.setBorder(new TitledBorder("写消息"));
 southPanel.add(txt_message, "Center");
 southPanel.add(btn_send, "East");
 leftPanel = new JScrollPane(userList);
 leftPanel.setBorder(new TitledBorder("在线用户"));
 
 rightPanel = new JScrollPane(contentArea);
 rightPanel.setBorder(new TitledBorder("群聊消息显示区"));
 
 centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,
  rightPanel);
 centerSplit.setDividerLocation(100);
 northPanel = new JPanel();
 northPanel.setLayout(new GridLayout(1, 6));
 northPanel.add(new JLabel("人数上限"));
 northPanel.add(txt_max);
 northPanel.add(new JLabel("端口"));
 northPanel.add(txt_port);
 northPanel.add(btn_start);
 northPanel.add(btn_stop);
 northPanel.setBorder(new TitledBorder("配置信息"));
 
 frame.setLayout(new BorderLayout());
 frame.add(northPanel, "North");
 frame.add(centerSplit, "Center");
 frame.add(southPanel, "South");
 frame.setSize(600, 400);
 //frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());//设置全屏
 int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 frame.setLocation((screen_width - frame.getWidth()) / 2,
  (screen_height - frame.getHeight()) / 2);
 frame.setVisible(true);
 
 // 关闭窗口时事件
 frame.addWindowListener(new WindowAdapter() 
 {
  public void windowClosing(WindowEvent e) 
  {
  if (isStart) {
   closeServer();// 关闭服务器
  }
  System.exit(0);// 退出程序
  }
 });
 
 // 文本框按回车键时事件
 txt_message.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  send();
  }
 });
 
 // 单击发送按钮时事件
 btn_send.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent arg0) 
  {
  send();
  }
 });
 
 // 单击启动服务器按钮时事件
 btn_start.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  if (isStart) {
   JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",
    "错误", JOptionPane.ERROR_MESSAGE);
   return;
  }
  int max;
  int port;
  try {
   try {
   max = Integer.parseInt(txt_max.getText());
   } catch (Exception e1) {
   throw new Exception("人数上限为正整数!");
   }
   if (max <= 0) {
   throw new Exception("人数上限为正整数!");
   }
   try {
   port = Integer.parseInt(txt_port.getText());
   } catch (Exception e1) {
   throw new Exception("端口号为正整数!");
   }
   if (port <= 0) {
   throw new Exception("端口号 为正整数!");
   }
   serverStart(max, port);
   contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port
    + "\r\n");
   JOptionPane.showMessageDialog(frame, "服务器成功启动!");
   btn_start.setEnabled(false);
   txt_max.setEnabled(false);
   txt_port.setEnabled(false);
   btn_stop.setEnabled(true);
  } catch (Exception exc) {
   JOptionPane.showMessageDialog(frame, exc.getMessage(),
    "错误", JOptionPane.ERROR_MESSAGE);
  }
  }
 });
 
 // 单击停止服务器按钮时事件
 btn_stop.addActionListener(new ActionListener() 
 {
  public void actionPerformed(ActionEvent e) 
  {
  if (!isStart) {
   JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",
    JOptionPane.ERROR_MESSAGE);
   return;
  }
  try {
   closeServer();
   btn_start.setEnabled(true);
   txt_max.setEnabled(true);
   txt_port.setEnabled(true);
   btn_stop.setEnabled(false);
   contentArea.append("服务器成功停止!\r\n");
   JOptionPane.showMessageDialog(frame, "服务器成功停止!");
  } catch (Exception exc) {
   JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",
    JOptionPane.ERROR_MESSAGE);
  }
  }
 });
 }
 
 // 启动服务器
 public void serverStart(int max, int port) throws java.net.BindException 
 {
 try {
  clients = new ArrayList();
  serverSocket = new ServerSocket(port);
  serverThread = new ServerThread(serverSocket, max);
  serverThread.start();
  isStart = true;
 } catch (BindException e) {
  isStart = false;
  throw new BindException("端口号已被占用,请换一个!");
 } catch (Exception e1) {
  e1.printStackTrace();
  isStart = false;
  throw new BindException("启动服务器异常!");
 }
 }
 
 // 关闭服务器
 @SuppressWarnings("deprecation")
 public void closeServer() {
 try {
  if (serverThread != null)
  serverThread.stop();// 停止服务器线程
 
  for (int i = clients.size() - 1; i >= 0; i--) {
  // 给所有在线用户发送关闭命令
  clients.get(i).getWriter().println("CLOSE");
  clients.get(i).getWriter().flush();
  // 释放资源
  clients.get(i).stop();// 停止此条为客户端服务的线程
  clients.get(i).reader.close();
  clients.get(i).writer.close();
  clients.get(i).socket.close();
  clients.remove(i);
  }
  if (serverSocket != null) {
  serverSocket.close();// 关闭服务器端连接
  }
  listModel.removeAllElements();// 清空用户列表
  isStart = false;
 } catch (IOException e) {
  e.printStackTrace();
  isStart = true;
 }
 }
 
 // 群发服务器消息
 public void sendServerMessage(String message) {
 for (int i = clients.size() - 1; i >= 0; i--) {
  clients.get(i).getWriter().println("服务器:" + message);
  clients.get(i).getWriter().flush();
 }
 }
 
 // 服务器线程
 class ServerThread extends Thread {
 private ServerSocket serverSocket;
 private int max;// 人数上限
 
 // 服务器线程的构造方法
 public ServerThread(ServerSocket serverSocket, int max) {
  this.serverSocket = serverSocket;
  this.max = max;
 }
 
 public void run() {
  while (true) {// 不停的等待客户端的链接
  try {
   Socket socket = serverSocket.accept();
   if (clients.size() == max) {// 如果已达人数上限
   BufferedReader r = new BufferedReader(
    new InputStreamReader(socket.getInputStream()));
   PrintWriter w = new PrintWriter(socket
    .getOutputStream());
   // 接收客户端的基本用户信息
   String inf = r.readLine();
   StringTokenizer st = new StringTokenizer(inf, "@");
   User user = new User(st.nextToken(), st.nextToken());
   // 反馈连接成功信息
   w.println("MAX@服务器:对不起," + user.getName()
    + user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");
   w.flush();
   // 释放资源
   r.close();
   w.close();
   socket.close();
   continue;
   }
   ClientThread client = new ClientThread(socket);
   client.start();// 开启对此客户端服务的线程
   clients.add(client);
   listModel.addElement(client.getUser().getName());// 更新在线列表
   contentArea.append(client.getUser().getName()
    + client.getUser().getIp() + "上线!\r\n");
  } catch (IOException e) {
   e.printStackTrace();
  }
  }
 }
 }
 
 // 为一个客户端服务的线程
 class ClientThread extends Thread 
 {
 private Socket socket;
 private BufferedReader reader;
 private PrintWriter writer;
 private User user;
 
 public BufferedReader getReader() 
 {
  return reader;
 }
 
 public PrintWriter getWriter() 
 {
  return writer;
 }
 
 public User getUser() 
 {
  return user;
 }
 
 // 客户端线程的构造方法
 public ClientThread(Socket socket) 
 {
  try {
  this.socket = socket;
  reader = new BufferedReader(new InputStreamReader(socket
   .getInputStream()));
  writer = new PrintWriter(socket.getOutputStream());
  // 接收客户端的基本用户信息
  String inf = reader.readLine();
  StringTokenizer st = new StringTokenizer(inf, "@");
  user = new User(st.nextToken(), st.nextToken());
  // 反馈连接成功信息
  writer.println(user.getName() + user.getIp() + "与服务器连接成功!");
  writer.flush();
  // 反馈当前在线用户信息
  if (clients.size() > 0) 
  {
   String temp = "";
   for (int i = clients.size() - 1; i >= 0; i--) 
   {
   temp += (clients.get(i).getUser().getName() + "/" + clients
    .get(i).getUser().getIp())
    + "@";
   }
   writer.println("USERLIST@" + clients.size() + "@" + temp);
   writer.flush();
  }
  // 向所有在线用户发送该用户上线命令
  for (int i = clients.size() - 1; i >= 0; i--) 
  {
   clients.get(i).getWriter().println(
    "ADD@" + user.getName() + user.getIp());
   clients.get(i).getWriter().flush();
  }
  } catch (IOException e) 
  {
  e.printStackTrace();
  }
 }
 
 @SuppressWarnings("deprecation")
 public void run() {// 不断接收客户端的消息,进行处理。
  String message = null;
  while (true) {
  try {
   message = reader.readLine();// 接收客户端消息
   if (message.equals("CLOSE"))// 下线命令
   {
   contentArea.append(this.getUser().getName()
    + this.getUser().getIp() + "下线!\r\n");
   // 断开连接释放资源
   reader.close();
   writer.close();
   socket.close();
 
   // 向所有在线用户发送该用户的下线命令
   for (int i = clients.size() - 1; i >= 0; i--) 
   {
    clients.get(i).getWriter().println(
     "DELETE@" + user.getName());
    clients.get(i).getWriter().flush();
   }
 
   listModel.removeElement(user.getName());// 更新在线列表
 
   // 删除此条客户端服务线程
   for (int i = clients.size() - 1; i >= 0; i--) 
   {
    if (clients.get(i).getUser() == user) 
    {
    ClientThread temp = clients.get(i);
    clients.remove(i);// 删除此用户的服务线程
    temp.stop();// 停止这条服务线程
    return;
    }
   }
   } else {
   dispatcherMessage(message);// 转发消息
   }
  } catch (IOException e) 
  {
   e.printStackTrace();
  }
  }
 }
 
 // 转发消息
 public void dispatcherMessage(String message) 
 {
  StringTokenizer stringTokenizer = new StringTokenizer(message, "@");
  String source = stringTokenizer.nextToken();
  String owner = stringTokenizer.nextToken();
  String cOntent= stringTokenizer.nextToken();
  message = source + "说:" + content;
  contentArea.append(message + "\r\n");
  if (owner.equals("ALL")) {// 群发
  for (int i = clients.size() - 1; i >= 0; i--) {
   clients.get(i).getWriter().println(message);
   clients.get(i).getWriter().flush();
  }
  }
 }
 }
}

运行截图

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


推荐阅读
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文详细介绍了W3C标准盒模型和IE传统盒模型的区别,探讨了CSS3中box-sizing属性的使用方法及其在布局中的重要性。通过实例分析,帮助读者更好地理解和应用这一关键概念。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • 本文详细探讨了Netty中Future及其子类的设计与实现,包括其在并发编程中的作用和具体应用场景。我们将介绍Future的继承体系、关键方法的实现细节,并讨论如何通过监听器和回调机制来处理异步任务的结果。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文介绍如何在 Unity 的 XML 配置文件中,将参数传递给自定义生命周期管理器的构造函数。我们将详细探讨 CustomLifetimeManager 类的实现及其配置方法。 ... [详细]
  • Ralph的Kubernetes进阶之旅:集群架构与对象解析
    本文深入探讨了Kubernetes集群的架构和核心对象,详细介绍了Pod、Service、Volume等基本组件,以及更高层次的抽象如Deployment、StatefulSet等,帮助读者全面理解Kubernetes的工作原理。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 本文详细探讨了Java中StringBuffer类在不同情况下的扩容规则,包括空参构造、带初始字符串和指定初始容量的构造方法。通过实例代码和理论分析,帮助读者更好地理解StringBuffer的内部工作原理。 ... [详细]
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文探讨了在Linux系统上使用Docker时,通过volume将主机上的HTML5文件挂载到容器内部指定目录时遇到的403错误,并提供了解决方案和详细的操作步骤。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
author-avatar
Q小泓别_431
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有