欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于java編寫局域網(wǎng)多人聊天室

 更新時間:2021年06月25日 13:27:20   作者:chance2015  
這篇文章主要為大家詳細介紹了基于java編寫局域網(wǎng)多人聊天室的相關資料,使用socket基于java編寫一個局域網(wǎng)聊天室,具有一定的參考價值,感興趣的小伙伴們可以參考一下

由于需要制作網(wǎng)絡計算機網(wǎng)絡課程設計,并且不想搞網(wǎng)絡布線或者局域網(wǎng)路由器配置等等這種完全搞不懂的東西,最后決定使用socket基于java編寫一個局域網(wǎng)聊天室:

關于socket以及網(wǎng)絡編程的相關知識詳見我另一篇文章:Java基于socket編程

程序基于C/S結構,即客戶端服務器模式。

服務器:

默認ip為本機ip
需要雙方確定一個端口號
可設置最大連接人數(shù)
可啟動與關閉
界面顯示在線用戶人以及姓名(本機不在此顯示)

客戶端:

需要手動設置服務器ip地址(局域網(wǎng))
手動設置端口號
輸入姓名
可連接可斷開

程序運行界面如下:

服務器:

客戶端:

具體代碼我會在最后上傳。

軟件有很多不足,其中比如:

沒有與數(shù)據(jù)庫有任何交集
優(yōu)化:可將所有用戶存放在數(shù)據(jù)庫中,以及將聊天記錄也放入數(shù)據(jù)庫中

沒有實現(xiàn)一對一聊天
優(yōu)化:需重新定義一對一聊天的方法

還有許多不足的地方,日后有興趣再回來慢慢研究

下面為該程序三個代碼:

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;  //設置最大連接人數(shù)
 private JTextField txt_port; //設置端口號
 private JButton btn_start;  //開始按鈕
 private JButton btn_stop;  //斷開按鈕
 private JButton btn_send;  //發(fā)送按鈕
 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;

 // 主方法,程序執(zhí)行入口
 public static void main(String[] args) {
  new Server_more();
 }

 // 執(zhí)行消息發(fā)送
 public void send() {
  if (!isStart) {
   JOptionPane.showMessageDialog(frame, "服務器還未啟動,不能發(fā)送消息!", "錯誤",
     JOptionPane.ERROR_MESSAGE);
   return;
  }
  if (clients.size() == 0) {
   JOptionPane.showMessageDialog(frame, "沒有用戶在線,不能發(fā)送消息!", "錯誤",
     JOptionPane.ERROR_MESSAGE);
   return;
  }
  String message = txt_message.getText().trim();
  if (message == null || message.equals("")) {
   JOptionPane.showMessageDialog(frame, "消息不能為空!", "錯誤",
     JOptionPane.ERROR_MESSAGE);
   return;
  }
  sendServerMessage(message);// 群發(fā)服務器消息
  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("發(fā)送");
  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("消息顯示區(qū)"));

  centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,
    rightPanel);
  centerSplit.setDividerLocation(100);
  northPanel = new JPanel();
  northPanel.setLayout(new GridLayout(1, 6));
  northPanel.add(new JLabel("人數(shù)上限"));
  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();
   }
  });

  // 單擊發(fā)送按鈕時事件
  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, "服務器已處于啟動狀態(tài),不要重復啟動!",
       "錯誤", JOptionPane.ERROR_MESSAGE);
     return;
    }
    int max;
    int port;
    try {
     try {
      max = Integer.parseInt(txt_max.getText());
     } catch (Exception e1) {
      throw new Exception("人數(shù)上限為正整數(shù)!");
     }
     if (max <= 0) {
      throw new Exception("人數(shù)上限為正整數(shù)!");
     }
     try {
      port = Integer.parseInt(txt_port.getText());
     } catch (Exception e1) {
      throw new Exception("端口號為正整數(shù)!");
     }
     if (port <= 0) {
      throw new Exception("端口號 為正整數(shù)!");
     }
     serverStart(max, port);
     contentArea.append("服務器已成功啟動!人數(shù)上限:" + 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, "停止服務器發(fā)生異常!", "錯誤",
       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--) {
    // 給所有在線用戶發(fā)送關閉命令
    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;
  }
 }

 // 群發(fā)服務器消息
 public void sendServerMessage(String message) {
  for (int i = clients.size() - 1; i >= 0; i--) {
   clients.get(i).getWriter().println("服務器:" + message + "(多人發(fā)送)");
   clients.get(i).getWriter().flush();
  }
 }

 // 服務器線程
 class ServerThread extends Thread {
  private ServerSocket serverSocket;
  private int max;// 人數(shù)上限

  // 服務器線程的構造方法
  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) {// 如果已達人數(shù)上限
      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() + ",服務器在線人數(shù)已達上限,請稍后嘗試連接!");
      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();
    }
    // 向所有在線用戶發(fā)送該用戶上線命令
    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();

      // 向所有在線用戶發(fā)送該用戶的下線命令
      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);// 轉發(fā)消息
     }
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }

  // 轉發(fā)消息
  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")) {// 群發(fā)
    for (int i = clients.size() - 1; i >= 0; i--) {
     clients.get(i).getWriter().println(message + "(多人發(fā)送)");
     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();
 }

 // 執(zhí)行發(fā)送
 public void send() {
  if (!isConnected) {
   JOptionPane.showMessageDialog(frame, "還沒有連接服務器,無法發(fā)送消息!", "錯誤",
     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("發(fā)送");
  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("消息顯示區(qū)"));
  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();
   }
  });

  // 單擊發(fā)送按鈕時事件
  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, "已處于連接上狀態(tài),不要重復連接!",
       "錯誤", JOptionPane.ERROR_MESSAGE);
     return;
    }
    try {
     try {
      port = Integer.parseInt(txt_port.getText().trim());
     } catch (NumberFormatException e2) {
      throw new Exception("端口號不符合要求!端口為整數(shù)!");
     }
     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, "已處于斷開狀態(tài),不要重復斷開!",
       "錯誤", JOptionPane.ERROR_MESSAGE);
     return;
    }
    try {
     boolean flag = closeConnection();// 斷開連接
     if (flag == false) {
      throw new Exception("斷開連接發(fā)生異常!");
     }
     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);// 根據(jù)端口號和服務器ip建立連接
   writer = new PrintWriter(socket.getOutputStream());
   reader = new BufferedReader(new InputStreamReader(socket
     .getInputStream()));
   // 發(fā)送客戶端用戶基本信息(用戶名和ip地址)
   sendMessage(name + "@" + socket.getLocalAddress().toString());
   // 開啟接收消息的線程
   messageThread = new MessageThread(reader, textArea);
   messageThread.start();
   isConnected = true;// 已經(jīng)連接上了
   return true;
  } catch (Exception e) {
   textArea.append("與端口號為:" + port + " IP地址為:" + hostIp
     + " 的服務器連接失敗!" + "\r\n");
   isConnected = false;// 未連接上
   return false;
  }
 }

 /**
  * 發(fā)送消息
  * 
  * @param message
  */
 public void sendMessage(String message) {
  writer.println(message);
  writer.flush();
 }

 /**
  * 客戶端主動關閉連接
  */
 @SuppressWarnings("deprecation")
 public synchronized boolean closeConnection() {
  try {
   sendMessage("CLOSE");// 發(fā)送斷開連接命令給服務器
   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;// 修改狀態(tài)為斷開
  }

  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")) {// 人數(shù)已達上限
      textArea.append(stringTokenizer.nextToken()
        + stringTokenizer.nextToken() + "\r\n");
      closeCon();// 被動的關閉連接
      JOptionPane.showMessageDialog(frame, "服務器緩沖區(qū)已滿!", "錯誤",
        JOptionPane.ERROR_MESSAGE);
      return;// 結束線程
     } else {// 普通消息
      textArea.append(message + "\r\n");
     }
    } catch (IOException e) {
     e.printStackTrace();
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  }
 }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • SpringCloud中的Hystrix保護機制詳解

    SpringCloud中的Hystrix保護機制詳解

    這篇文章主要介紹了SpringCloud中的Hystrix保護機制詳解,Hystrix,英文意思是豪豬,全身是刺,看起來就不好惹,是一種保護機制,Hystrix也是Netflix公司的一款組件,需要的朋友可以參考下
    2023-12-12
  • SpringMVC框架和SpringBoot項目中控制器的響應結果深入分析

    SpringMVC框架和SpringBoot項目中控制器的響應結果深入分析

    這篇文章主要介紹了SpringMVC框架和SpringBoot項目中控制器的響應結果,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-12-12
  • Java實現(xiàn)自定義Excel數(shù)據(jù)排序的方法詳解

    Java實現(xiàn)自定義Excel數(shù)據(jù)排序的方法詳解

    通常,我們可以在Excel中對指定列數(shù)據(jù)執(zhí)行升序或者降序排序,在需要自定義排序情況下,我們也可以自行根據(jù)排序需要編輯數(shù)據(jù)排列順序。本文將通過Java應用程序來實現(xiàn)如何自定義排序,需要的可以參考一下
    2022-09-09
  • SpringSecurity默認登錄頁的使用示例教程

    SpringSecurity默認登錄頁的使用示例教程

    Spring 是非常流行和成功的 Java 應用開發(fā)框架,Spring Security 正是 Spring 家族中的成員,Spring Security 基于 Spring 框架,提供了一套 Web 應用安全性的完整解決方案,本文給大家介紹SpringSecurity的默認登錄頁的使用教程,感興趣的朋友一起看看吧
    2023-12-12
  • 詳解JavaWeb過濾器 Filter問題解決

    詳解JavaWeb過濾器 Filter問題解決

    過濾器就是對事物進行過濾的,在Web中的過濾器,當然就是對請求進行過濾,我們使用過濾器,就可以對請求進行攔截,然后做相應的處理,實現(xiàn)許多特殊功能,今天主要給大家講解JavaWeb過濾器 Filter問題解決,感興趣的朋友一起看看吧
    2022-10-10
  • Go?Java算法猜數(shù)字游戲示例詳解

    Go?Java算法猜數(shù)字游戲示例詳解

    這篇文章主要為大家介紹了Go?Java算法猜數(shù)字游戲示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • SpringBoot詳細講解yaml配置文件的用法

    SpringBoot詳細講解yaml配置文件的用法

    這篇文章主要介紹了SpringBoot中的yaml配置文件問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 詳解Spring?Boot中@PostConstruct的使用示例代碼

    詳解Spring?Boot中@PostConstruct的使用示例代碼

    在Java中,@PostConstruct是一個注解,通常用于標記一個方法,它表示該方法在類實例化之后(通過構造函數(shù)創(chuàng)建對象之后)立即執(zhí)行,這篇文章主要介紹了詳解Spring?Boot中@PostConstruct的使用,需要的朋友可以參考下
    2023-09-09
  • springboot整合JPA訪問Mysql的實現(xiàn)方法

    springboot整合JPA訪問Mysql的實現(xiàn)方法

    本文主要介紹了springboot整合JPA訪問Mysql的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 淺談springboot @Repository與@Mapper的區(qū)別

    淺談springboot @Repository與@Mapper的區(qū)別

    本文主要介紹了淺談springboot @Repository與@Mapper的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評論