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

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

这篇文章主要介绍了基于java编写局域网多人聊天室的相关资料,使用socket基于java编写一个局域网聊天室,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

由于需要制作网络计算机网络课程设计,并且不想搞网络布线或者局域网路由器配置等等这种完全搞不懂的东西,最后决定使用socket基于java编写一个局域网聊天室:

关于socket以及网络编程的相关知识详见我另一篇文章:Java基于socket编程

程序基于C/S结构,即客户端服务器模式。
服务器:
默认ip为本机ip
需要双方确定一个端口号
可设置最大连接人数
可启动与关闭
界面显示在线用户人以及姓名(本机不在此显示)
客户端:
需要手动设置服务器ip地址(局域网)
手动设置端口号
输入姓名
可连接可断开
程序运行界面如下:

服务器:

客户端:

具体代码我会在最后上传。
软件有很多不足,其中比如:
没有与数据库有任何交集
优化:可将所有用户存放在数据库中,以及将聊天记录也放入数据库中
没有实现一对一聊天
优化:需重新定义一对一聊天的方法
还有许多不足的地方,日后有兴趣再回来慢慢研究

下面为该程序三个代码:
User.java

public class User{
 /**
  * 用户信息类
  * 用于记录用户个人信息:姓名以及IP
  */
 private String name;
 private String ip;

 public User(String name, String ip) {
  this.name = name;
  this.ip = ip;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getIp() {
  return ip;
 }
 public void setIp(String ip) {
  this.ip = ip;
 }
}

Server_more.java

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_more {

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

 // 执行消息发送
 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_more() {
  frame = new JFrame("服务器");
  // 更改JFrame的图标:
  //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));
  //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png")));
  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();
    }
   }
  }
 }
}

Client_more.java

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.Socket;
import java.util.HashMap;
import java.util.Map;
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 Client_more{

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

 // 执行发送
 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_more() {
  textArea = new JTextArea();
  textArea.setEditable(false);
  textArea.setForeground(Color.blue);
  textField = new JTextField();
  txt_port = new JTextField("6666");
  txt_hostIp = new JTextField("127.0.0.1");
  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.png")));
  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);
    }
   }
  });

  // 单击断开按钮时事件
  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 

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


推荐阅读
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了在Hibernate配置lazy=false时无法加载数据的问题,通过采用OpenSessionInView模式和修改数据库服务器版本解决了该问题。详细描述了问题的出现和解决过程,包括运行环境和数据库的配置信息。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 本文详细介绍了云服务器API接口的概念和作用,以及如何使用API接口管理云上资源和开发应用程序。通过创建实例API、调整实例配置API、关闭实例API和退还实例API等功能,可以实现云服务器的创建、配置修改和销毁等操作。对于想要学习云服务器API接口的人来说,本文提供了详细的入门指南和使用方法。如果想进一步了解相关知识或阅读更多相关文章,请关注编程笔记行业资讯频道。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 如何基于ggplot2构建相关系数矩阵热图以及一个友情故事
    本文介绍了如何在rstudio中安装ggplot2,并使用ggplot2构建相关系数矩阵热图。同时,通过一个友情故事,讲述了真爱难觅的故事背后的数据量化和皮尔逊相关系数的概念。故事中的小伙伴们在本科时参加各种考试,其中有些沉迷网络游戏,有些热爱体育,通过他们的故事,展示了不同兴趣和特长对学习和成绩的影响。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
author-avatar
zoooooz
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有