多线程Java简易聊天室

客户端:

 

 import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

 

import javax.swing.*;

 

public class Client {

 private JFrame clientFrame;

 private JLabel IPLabel;

 private JLabel PortLabel;

 private JLabel sayLabel;

 private JLabel nicknameLabel;

 private JTextField IPText;

 private JTextField PortText;

 private JTextField nicknameText;

 private JTextField sayText;

 private JButton connectButton;

 private JButton nicknameButton;

 private JButton sayButton;

 private JPanel jPanelNorth;

 private JPanel jPanelSouth0;

 private JPanel jPanelSouth1;

 private JPanel jPanelSouth2;

 private JTextArea clientTextArea;

 private JScrollPane scroller;

 private BufferedReader reader;

 private PrintWriter writer;

 private String nickname;

 

 public static void main(String args[]) {

  Client aClient = new Client();

  aClient.startUp();

 }

 

 // 初始化组件

 public Client() {

  nickname = "客户端";

 

  clientFrame = new JFrame();

  jPanelNorth = new JPanel();

  IPLabel = new JLabel("服务器IP", JLabel.LEFT);

  IPText = new JTextField(10);

  PortLabel = new JLabel("服务器端口", JLabel.LEFT);

  PortText = new JTextField(10);

  connectButton = new JButton("连接");

  clientTextArea = new JTextArea();

  scroller = new JScrollPane(clientTextArea);

  jPanelSouth0 = new JPanel();

  jPanelSouth1 = new JPanel();

  jPanelSouth2 = new JPanel();

  nicknameLabel = new JLabel("昵称", JLabel.LEFT);

  nicknameText = new JTextField(nickname, 30);

  nicknameButton = new JButton("确认");

  sayLabel = new JLabel("消息", JLabel.LEFT);

  sayText = new JTextField(30);

  sayButton = new JButton("确认");

 }

 

 // 构建GUI

 private void buildGUI() {

  // 窗口的设置

  clientFrame.setTitle("客户端");

  clientFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  clientFrame.setSize(550, 550);

 

  // 北区的组件

  jPanelNorth.add(IPLabel);

  jPanelNorth.add(IPText);

  jPanelNorth.add(PortLabel);

  jPanelNorth.add(PortText);

  jPanelNorth.add(connectButton);

  clientFrame.getContentPane().add(BorderLayout.NORTH, jPanelNorth);

 

  // 中间的组件

  clientTextArea.setFocusable(false);

  scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

  scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

  clientFrame.getContentPane().add(BorderLayout.CENTER, scroller);

 

  // 南区的组件

  jPanelSouth1.add(nicknameLabel);

  jPanelSouth1.add(nicknameText);

  jPanelSouth1.add(nicknameButton);

  jPanelSouth2.add(sayLabel);

  jPanelSouth2.add(sayText);

  jPanelSouth2.add(sayButton);

  jPanelSouth0.setLayout(new BoxLayout(jPanelSouth0, BoxLayout.Y_AXIS));

  jPanelSouth0.add(jPanelSouth1);

  jPanelSouth0.add(jPanelSouth2);

  clientFrame.getContentPane().add(BorderLayout.SOUTH, jPanelSouth0);

 

  // 设置窗口可见

  clientFrame.setVisible(true);

 }

 

 // 客户端运行

 public void startUp() {

  buildGUI();

 

  // 接收服务器消息的线程

  Runnable incomingReader = new Runnable() {

   @Override

   public void run() {

    String message;

    try {

     while ((message = reader.readLine()) != null) {

      clientTextArea.append(message + "\n");

     }

    } catch (Exception ex) {

     ex.printStackTrace();

    }

   }

  };

 

  // 监听Connect按钮,实现服务器的连接

  connectButton.addActionListener(new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    String aServerIP = IPText.getText();

    String aServerPort = PortText.getText();

 

    if (aServerIP.equals("") || aServerPort.equals("")) {

     JOptionPane.showMessageDialog(clientFrame, "请输入完整的 IP和端口!");

    } else {

     try {

      @SuppressWarnings("resource")

      Socket clientSocket = new Socket(aServerIP, Integer.parseInt(aServerPort));

      InputStreamReader streamReader = new InputStreamReader(clientSocket.getInputStream());

      reader = new BufferedReader(streamReader);

      writer = new PrintWriter(clientSocket.getOutputStream());

 

      clientTextArea.append("服务器已连接...\n");

 

      Thread readerThread = new Thread(incomingReader);

      readerThread.start();

     } catch (Exception ex) {

      JOptionPane.showMessageDialog(clientFrame, "连接不上服务器!\n请确认 IP 端口输入正确。");

     }

    }

   }

  });

 

  // 监听nickname,设置昵称

  ActionListener nicknameListener = new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    String aText = nicknameText.getText();

    if (!aText.equals("")) {

     nickname = aText;

    }

   }

  };

  nicknameButton.addActionListener(nicknameListener);

  nicknameText.addActionListener(nicknameListener);

  nicknameText.addFocusListener(new FocusListener() {

   @Override

   public void focusGained(FocusEvent e) {

   }

 

   @Override

   public void focusLost(FocusEvent e) {

    String aText = nicknameText.getText();

    if (!aText.equals("")) {

     nickname = aText;

    }

   }

  });

 

  // 发送消息到服务器

  ActionListener SayListener = new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    String aText = sayText.getText();

    if (aText.equals("")) {

     JOptionPane.showMessageDialog(clientFrame, "内容不能为空!");

    } else {

     try {

      writer.println(nickname + "" + aText);

      writer.flush();

     } catch (Exception ex) {

      ex.printStackTrace();

     }

     sayText.setText("");

    }

   }

  };

  sayButton.addActionListener(SayListener);

  sayText.addActionListener(SayListener);

 

 }

 

}

 

服务器:

 

 

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

import java.util.ArrayList;

import java.util.Iterator;

import javax.swing.*;

 

public class Server {

 private JFrame serverFrame;

 private JLabel portLabel;

 private JLabel sayLabel;

 private JLabel nicknameLabel;

 private JTextField portText;

 private JTextField sayText;

 private JTextField nicknameText;

 private JButton startButton;

 private JButton sayButton;

 private JButton nicknameButton;

 private JPanel jPanelNorth;

 private JPanel jPanelSouth0;

 private JPanel jPanelSouth1;

 private JPanel jPanelSouth2;

 private JScrollPane scroller;

 private JTextArea serverTextArea;

 private ArrayList<PrintWriter> clientOutputStreams;

 private String nickname;

 

 public static void main(String[] args) {

  Server aServer = new Server();

  aServer.startUp();

 }

 

 // 初始化组件

 public Server() {

  nickname = "服务器";

 

  serverFrame = new JFrame();

  jPanelNorth = new JPanel();

  portLabel = new JLabel("端口", JLabel.LEFT);

  portText = new JTextField(30);

  startButton = new JButton("开始");

  serverTextArea = new JTextArea();

  scroller = new JScrollPane(serverTextArea);

  nicknameLabel = new JLabel("昵称", JLabel.LEFT);

  nicknameText = new JTextField(nickname, 30);

  nicknameButton = new JButton("确认");

  jPanelSouth0 = new JPanel();

  jPanelSouth1 = new JPanel();

  jPanelSouth2 = new JPanel();

  sayLabel = new JLabel("消息", JLabel.LEFT);

  sayText = new JTextField(30);

  sayButton = new JButton("确认");

 }

 

 // 构建GUI

 private void buildGUI() {

  // 窗口的设置

  serverFrame.setTitle("服务器");

  serverFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  serverFrame.setSize(550, 550);

 

  // 北区的组件

  jPanelNorth.add(portLabel);

  jPanelNorth.add(portText);

  jPanelNorth.add(startButton);

  serverFrame.getContentPane().add(BorderLayout.NORTH, jPanelNorth);

 

  // 中间的组件

  serverTextArea.setFocusable(false);

  scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

  scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

  serverFrame.getContentPane().add(BorderLayout.CENTER, scroller);

 

  // 南区的组件

  jPanelSouth1.add(nicknameLabel);

  jPanelSouth1.add(nicknameText);

  jPanelSouth1.add(nicknameButton);

  jPanelSouth2.add(sayLabel);

  jPanelSouth2.add(sayText);

  jPanelSouth2.add(sayButton);

  jPanelSouth0.setLayout(new BoxLayout(jPanelSouth0, BoxLayout.Y_AXIS));

  jPanelSouth0.add(jPanelSouth1);

  jPanelSouth0.add(jPanelSouth2);

  serverFrame.getContentPane().add(BorderLayout.SOUTH, jPanelSouth0);

 

  // 设置窗口可见

  serverFrame.setVisible(true);

 }

 

 // 服务器运行

 public void startUp() {

  buildGUI();

 

  // 监听Start按钮,建立端口

  ActionListener startListener = new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    clientOutputStreams = new ArrayList<PrintWriter>();

    String aPort = portText.getText();

 

    if (aPort.equals("")) {

     JOptionPane.showMessageDialog(serverFrame, "请输入正确的端口号!");

    } else {

     try {

      // 等待客户端连接的线程

      Runnable serverRunnable = new Runnable() {

       @Override

       public void run() {

        ServerSocket serverSocket;

        try {

         serverSocket = newServerSocket(Integer.parseInt(aPort));

         serverTextArea.append("正在等待客户端连接...\n");

         while (true) {

          Socket clientSocket = serverSocket.accept();

          serverTextArea.append("客户端已连接...\n");

 

          PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());

          clientOutputStreams.add(writer);

 

          Thread t = new Thread(new ClientHandler(clientSocket));

          t.start();

         }

        } catch (NumberFormatException | IOException e) {

         e.printStackTrace();

        }

       }

      };

      Thread serverThread = new Thread(serverRunnable);

      serverThread.start();

     } catch (Exception ex) {

      ex.printStackTrace();

     }

    }

   }

  };

  startButton.addActionListener(startListener);

  portText.addActionListener(startListener);

 

  // 监听nickname,设置昵称

  ActionListener nicknameListener = new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    String aText = nicknameText.getText();

    if (!aText.equals("")) {

     nickname = aText;

    }

   }

  };

  nicknameButton.addActionListener(nicknameListener);

  nicknameText.addActionListener(nicknameListener);

  nicknameText.addFocusListener(new FocusListener() {

   @Override

   public void focusGained(FocusEvent e) {

   }

 

   @Override

   public void focusLost(FocusEvent e) {

    String aText = nicknameText.getText();

    if (!aText.equals("")) {

     nickname = aText;

    }

   }

  });

 

  // 监听Say按钮,发送消息

  ActionListener SayListener = new ActionListener() {

   @Override

   public void actionPerformed(ActionEvent e) {

    String aText = sayText.getText();

    if (!aText.equals("")) {

     aText = nickname + "" + aText;

     sendToEveryClient(aText);

     serverTextArea.append(aText + "\n");

     sayText.setText("");

    } else {

     JOptionPane.showMessageDialog(serverFrame, "内容不能为空!");

    }

   }

  };

  sayButton.addActionListener(SayListener);

  sayText.addActionListener(SayListener);

 }

 

 // 多客户端的线程

 public class ClientHandler implements Runnable {

  BufferedReader bReader;

  Socket aSocket;

 

  public ClientHandler(Socket clientSocket) {

   try {

    aSocket = clientSocket;

    InputStreamReader isReader = new InputStreamReader(aSocket.getInputStream());

    bReader = new BufferedReader(isReader);

   } catch (Exception ex) {

    ex.printStackTrace();

   }

  }

 

  @Override

  public void run() {

   String message;

   try {

    while ((message = bReader.readLine()) != null) {

     sendToEveryClient(message);

     serverTextArea.append(message + "\n");

    }

   } catch (Exception ex) {

    ex.printStackTrace();

   }

  }

 }

 

 // 发送消息给所有客户端的方法

 private void sendToEveryClient(String message) {

  Iterator<PrintWriter> it = clientOutputStreams.iterator();

  while (it.hasNext()) {

   try {

    PrintWriter writer = (PrintWriter) it.next();

    writer.println(message);

    writer.flush();

   } catch (Exception ex) {

    ex.printStackTrace();

   }

  }

 }

 

}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值