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

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

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

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

服务器:

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

客户端:

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

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

下面为该程序三个代码:
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<ClientThread> 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<ClientThread>();
   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<String, User> onLineUsers = new HashMap<String, User>();// 所有在线用户

 // 主方法,程序入口
 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 < size; i++) {
       username = stringTokenizer.nextToken();
       userIp = stringTokenizer.nextToken();
       User user = new User(username, userIp);
       onLineUsers.put(username, user);
       listModel.addElement(username);
      }
     } else if (command.equals("MAX")) {// 人数已达上限
      textArea.append(stringTokenizer.nextToken()
        + stringTokenizer.nextToken() + "\r\n");
      closeCon();// 被动的关闭连接
      JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",
        JOptionPane.ERROR_MESSAGE);
      return;// 结束线程
     } else {// 普通消息
      textArea.append(message + "\r\n");
     }
    } catch (IOException e) {
     e.printStackTrace();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }
 }
}

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

时间: 2016-09-06

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

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

基于Tomcat7、Java、WebSocket的服务器推送聊天室实例

前言 HTML5 WebSocket实现了服务器与浏览器的双向通讯,双向通讯使服务器消息推送开发更加简单,最常见的就是即时通讯和对信息实时性要求比较高的应用.以前的服务器消息推送大部分采用的都是"轮询"和"长连接"技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高.WebSocket技术对只会产生很小的开销,并且实时性特别高.下面就开始讲解如何利用WebSocket技术开发聊天室.在这个实例中,采用的是Tomcat7服务器,每个服务器对于WebSoc

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

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

Java continue break制作简单聊天室程序

Java continue break 制作简单聊天室程序,屏蔽不文明语言,显示每句话聊天时间 package com.swift; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; public class ChatWithBreakContinue { public static void main(String[] args) { Scanner scan = new Sc

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基于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基于UDP协议实现简单的聊天室程序

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

使用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 WebSocket做一个聊天室

最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了. 先看图: 实现了多客户机进行实时通讯. 下面看代码项目结构图:很简单,就1个类,1个页面 然后看具体代码 先看后端代码 package com.main; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.

php基于websocket搭建简易聊天室实践

本文实例讲述了php基于websocket搭建简易聊天室实践.分享给大家供大家参考.具体如下: 1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短连接和长连接.短连接一般可以用ajax实现,长连接就是websocket.短连接实现起来比较简单,但是太过于消耗资源.websocket高效不过兼容存在点问题.websocket是html5的资源 2.前

用Flash和XML来构造一个聊天室

点击这里下载源文件 前面的教程我们介绍了Flash与XML结合使用的原理以及一个论坛的实现,下面我们继续结合Flash与XML来实现一个简单的聊天室,有在线聊天.在线人员名单.在线时间.简单的管理操作等功能.根据需要在此基础上稍作修改,就可以实现一个功能比较完备的聊天室了. 一.原理 用Flash和XML来构造聊天室,跟直接用Flash和Asp来构造聊天室的基本原理是一样的.都是先在Flash端发送一个XML请求到服务器端,然后等待从服务器端的XML返回值,当值返回Flash端后,解释所返回的X

java利用Socket实现聊天室功能实例

最近研究了下Java socket通信基础,利用代码实现了一个简单的多人聊天室功能,现把代码共享下,希望能帮到有兴趣了解的人. 目录结构: ChatClient: package com.panda.chat; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; @SuppressWarnings("serial") public class ChatClient extend

基于Swoole实现PHP与websocket聊天室

websocket Websocket只是一个网络通信协议 就像 http.ftp等都是网络通信的协议:不要多想: 相对于HTTP这种非持久的协议来说,Websocket是一个持久化网络通信的协议: WebSocket和HTTP的关系 有交集,但是并不是全部. Websocket只是借用了HTTP的一部分协议来完成一次握手.(HTTP的三次握手,此处只完成一次) http和websocket 请求头对比: HTTP: 原来的时候,客户端通过http(骑马)带着信请求服务器,服务器处理请求(写回信

golang基于websocket实现的简易聊天室程序

本文实例讲述了golang基于websocket实现的简易聊天室.分享给大家供大家参考,具体如下: 先说点无关的,最近忙于工作没有更新博客,今天休息顺便把golang websocket研究了一下,挺好玩的,写了一个聊天室,分享给大家. websocket包 : code.google.com/p/go.net/websocket 文档 : http://go.pkgdoc.org/code.google.com/p/go.net/websocket 首先安装websocket包 复制代码 代码

vue + socket.io实现一个简易聊天室示例代码

vue + vuex + elementUi + socket.io实现一个简易的在线聊天室,提高自己在对vue系列在项目中应用的深度.因为学会一个库或者框架容易,但要结合项目使用一个库或框架就不是那么容易了.功能虽然不多,但还是有收获.设计和实现思路较为拙劣,恳请各位道友指正. 可以达到的需求 能查看在线用户列表 能发送和接受消息 使用到的框架和库 socket.io做为实时通讯基础 vuex/vue:客户端Ui层使用 Element-ui:客户端Ui组件 类文件关系图 服务端: 客户端: 服

ASP建立一个简单的聊天室

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