Java多線程完成聊天客戶端和辦事器。本站提示廣大學習愛好者:(Java多線程完成聊天客戶端和辦事器)文章只能為提供參考,不一定能成為您想要的結果。以下是Java多線程完成聊天客戶端和辦事器正文
本文實例為年夜家分享了java聊天室代碼,供年夜家參考,詳細內容以下
重要觸及常識
·Java中GUI法式的編寫,包含事宜監聽機制。
·Java的收集通訊編程,ServerSocket,Socket類的應用。
·Java中多線程的編程,Thread類,Runnable接口的應用。
源代碼
客戶端
package project1; 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); } }
辦事器
package project1; 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 = new ServerSocket(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(); } } } }
GUI運轉截圖:
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。