热门标签 | 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();
  }
  }
 }
 }
}

运行截图

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


推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 胡蜂能进行逻辑推理的研究成果
    最新研究表明,胡蜂具备一定的逻辑推理能力,能够进行传递性推理。研究人员通过实验发现,胡蜂在避免电击的测试中,能够正确选择符合逻辑的选项。这项研究成果对于了解无脊椎动物的认知能力具有重要意义,也为解析胡蜂社会结构的进化提供了线索。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • docker增加restart=always, docker重启后自动启动容器的方法
    本文介绍了在运行docker容器时如何添加参数来保证每次docker服务重启后容器也自动重启的方法,以及如何使用命令来更新已启动的容器。 ... [详细]
  • 处理docker容器时间和宿主机时间不一致问题的方法
    本文介绍了处理docker容器时间和宿主机时间不一致问题的方法,包括复制主机的localtime到容器、处理报错情况以及重启容器的步骤。通过这些方法,可以解决docker容器时间和宿主机时间不一致的问题。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文介绍了电流源并联合并的方法,以及谐振电路的原理。谐振电路具有很强的选频能力,通过将电感和电容连接在一起,电流和电压会产生震荡。谐振频率的大小取决于电感和电容的大小,而电路中的电阻会逐渐降低震荡的幅度。电阻和电容组成的电路中,当电容放完电后,电阻两端的电压为0,电流不再流过电容。然而,电感是一种特殊的器件,当有电流流过时,线圈会产生感应磁场,阻止电流的流动,从而使电流不会减小。 ... [详细]
  • 标题: ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 本文介绍了在Docker容器技术中限制容器对CPU的使用的方法,包括使用-c参数设置容器的内存限额,以及通过设置工作线程数量来充分利用CPU资源。同时,还介绍了容器权重分配的情况,以及如何通过top命令查看容器在CPU资源紧张情况下的使用情况。 ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
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社区 版权所有