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

Java編寫網(wǎng)絡(luò)聊天程序?qū)嶒?yàn)

 更新時(shí)間:2022年08月10日 11:42:59   作者:ThinkStu  
這篇文章主要為大家詳細(xì)介紹了Java編寫網(wǎng)絡(luò)聊天程序?qū)嶒?yàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java編寫網(wǎng)絡(luò)聊天程序的具體代碼,供大家參考,具體內(nèi)容如下

課程名稱 高級(jí)Java程序設(shè)計(jì)

實(shí)驗(yàn)項(xiàng)目 Java網(wǎng)絡(luò)編程

實(shí)驗(yàn)?zāi)康模?/strong>

使用客戶機(jī)/服務(wù)器模式、基于TCP協(xié)議編寫一對(duì)多“群聊”程序。其中客戶機(jī)端單擊“連接服務(wù)器”或“斷開連接”按鈕,均能即時(shí)更新服務(wù)器和所有客戶機(jī)的在線人數(shù)和客戶名。

實(shí)驗(yàn)要求:

設(shè)計(jì)一對(duì)多的網(wǎng)絡(luò)聊天程序,要求:

1、基于TCP/IP設(shè)計(jì)聊天程序
2、采用圖形界面設(shè)計(jì)
3、能夠進(jìn)行一對(duì)多聊天

項(xiàng)目截圖

服務(wù)器端代碼:

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Vector;
?
?
public class Server extends JFrame {
? ? // TODO 該圖形界面擁有三塊區(qū)域,分別位于上、中、下 (up、middle、down)。
? ? private JPanel panUp = new JPanel();
? ? private JPanel panMid = new JPanel();
? ? private JPanel panDown = new JPanel();
?
? ? // panUp 區(qū)域的子節(jié)點(diǎn)定義,標(biāo)簽、輸入框、按鈕
? ? private JLabel lblLocalPort = new JLabel("本機(jī)服務(wù)器監(jiān)聽端口:");
? ? protected JButton butStart = new JButton("啟動(dòng)服務(wù)器");
? ? protected JTextField tfLocalPort = new JTextField(25);
?
? ? // panMid 區(qū)域的子節(jié)點(diǎn)定義,顯示框 以及 滾動(dòng)條
? ? protected JTextArea taMsg = new JTextArea(25, 25);
? ? JScrollPane scroll = new JScrollPane(taMsg);
?
? ? // panDown 區(qū)域的子節(jié)點(diǎn)定義,lstUsers在線用戶界面
? ? JList lstUsers = new JList();
?
? ? // TODO 以下是存放數(shù)據(jù)的變量
? ? public static int localPort = 8000; ? ? // 默認(rèn)端口 8000
? ? static int SerialNum = 0; ? ? ? // 用戶連接數(shù)量
? ? ServerSocket serverSocket; ? ? ?// 服務(wù)器端 Socket
? ? ArrayList<AcceptRunnable.Client> clients = new ArrayList<>(); ? ? ? ?// 用戶連接對(duì)象數(shù)組
? ? Vector<String> clientNames = new Vector<>(); ? ? ? // lstUsers 中存放的數(shù)據(jù)
?
? ? // TODO 構(gòu)造方法
? ? public Server() {
? ? ? ? init();
? ? }
?
? ? // TODO 初始化方法:初始化圖形界面布局
? ? private void init() {
? ? ? ? // panUp 區(qū)域初始化:流式區(qū)域
? ? ? ? panUp.setLayout(new FlowLayout());
? ? ? ? panUp.add(lblLocalPort);
? ? ? ? panUp.add(tfLocalPort);
? ? ? ? panUp.add(butStart);
? ? ? ? tfLocalPort.setText(String.valueOf(localPort));
? ? ? ? butStart.addActionListener(new startServerHandler()); ? // 注冊(cè) "啟動(dòng)服務(wù)器" 按鈕點(diǎn)擊事件
?
? ? ? ? // panMid 區(qū)域初始化
? ? ? ? panMid.setBorder(new TitledBorder("監(jiān)聽消息"));
? ? ? ? taMsg.setEditable(false);
? ? ? ? panMid.add(scroll);
?
? ? ? ? // panDown 區(qū)域初始化
? ? ? ? panDown.setBorder(new TitledBorder("在線用戶"));
? ? ? ? panDown.add(lstUsers);
? ? ? ? lstUsers.setVisibleRowCount(10);
?
? ? ? ? // 圖形界面的總體初始化 + 啟動(dòng)圖形界面
? ? ? ? this.setTitle("服務(wù)器端");
? ? ? ? this.add(panUp, BorderLayout.NORTH);
? ? ? ? this.add(panMid, BorderLayout.CENTER);
? ? ? ? this.add(panDown, BorderLayout.SOUTH);
? ? ? ? this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
? ? ? ? this.setPreferredSize(new Dimension(600, 400));
? ? ? ? this.pack();
? ? ? ? this.setVisible(true);
? ? }
?
? ? // TODO “啟動(dòng)服務(wù)器”按鈕的動(dòng)作事件監(jiān)聽處理類
? ? private class startServerHandler implements ActionListener {
? ? ? ? @Override
? ? ? ? public void actionPerformed(ActionEvent e) {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? // 當(dāng)點(diǎn)擊按鈕時(shí),獲取端口設(shè)置并啟動(dòng)新進(jìn)程、監(jiān)聽端口
? ? ? ? ? ? ? ? localPort = Integer.parseInt(tfLocalPort.getText());
? ? ? ? ? ? ? ? serverSocket = new ServerSocket(localPort);
? ? ? ? ? ? ? ? Thread acptThrd = new Thread(new AcceptRunnable());
? ? ? ? ? ? ? ? acptThrd.start();
? ? ? ? ? ? ? ? taMsg.append("**** 服務(wù)器(端口" + localPort + ")已啟動(dòng) ****\n");
? ? ? ? ? ? } catch (Exception ex) {
? ? ? ? ? ? ? ? System.out.println(ex);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? // TODO 接受用戶連接請(qǐng)求的線程關(guān)聯(lián)類
? ? private class AcceptRunnable implements Runnable {
? ? ? ? public void run() {
? ? ? ? ? ? // 持續(xù)監(jiān)聽端口,當(dāng)有新用戶連接時(shí) 再開啟新進(jìn)程
? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? Socket socket = serverSocket.accept();
? ? ? ? ? ? ? ? ? ? // 新的用戶已連接,創(chuàng)建 Client 對(duì)象
? ? ? ? ? ? ? ? ? ? Client client = new Client(socket);
? ? ? ? ? ? ? ? ? ? taMsg.append("——客戶【" + client.nickname + "】加入\n");
? ? ? ? ? ? ? ? ? ? Thread clientThread = new Thread(client);
? ? ? ? ? ? ? ? ? ? clientThread.start();
? ? ? ? ? ? ? ? ? ? clients.add(client);
? ? ? ? ? ? ? ? } catch (Exception ex) {
? ? ? ? ? ? ? ? ? ? System.out.println(ex);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
?
? ? ? ? // TODO 服務(wù)器存放用戶對(duì)象的客戶類(主要編程)。每當(dāng)有新的用戶連接時(shí),該類都會(huì)被調(diào)用
? ? ? ? // TODO 該類繼承自 Runnable,內(nèi)部含有 run()方法
? ? ? ? private class Client implements Runnable {
? ? ? ? ? ? private Socket socket; ? ? ?// 用來保存用戶的連接對(duì)象
? ? ? ? ? ? private BufferedReader in; ? // IO 流
? ? ? ? ? ? private PrintStream out;
? ? ? ? ? ? private String nickname; ? ? ? ?// 保存用戶昵稱
?
? ? ? ? ? ? // Client類的構(gòu)建方法。當(dāng)有 新用戶 連接時(shí)會(huì)被調(diào)用
? ? ? ? ? ? public Client(Socket socket) throws Exception {
? ? ? ? ? ? ? ? this.socket = socket;
? ? ? ? ? ? ? ? InputStream is = socket.getInputStream();
? ? ? ? ? ? ? ? in = new BufferedReader(new InputStreamReader(is));
? ? ? ? ? ? ? ? OutputStream os = socket.getOutputStream();
? ? ? ? ? ? ? ? out = new PrintStream(os);
? ? ? ? ? ? ? ? nickname = in.readLine(); ? ? // 獲取用戶昵稱
? ? ? ? ? ? ? ? for (Client c : clients) { ? // 將新用戶的登錄消息發(fā)給所有用戶
? ? ? ? ? ? ? ? ? ? c.out.println("——客戶【" + nickname + "】加入\n");
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
?
? ? ? ? ? ? //客戶類線程運(yùn)行方法 ??
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? ? ? String usermsg ? = in.readLine(); ? //讀用戶發(fā)來消息
? ? ? ? ? ? ? ? ? ? ? ? String secondMsg = usermsg.substring(usermsg.lastIndexOf(":") + 1); ? // 字符串輔助對(duì)象
?
? ? ? ? ? ? ? ? ? ? ? ? // 如果用戶發(fā)過來的消息不為空
? ? ? ? ? ? ? ? ? ? ? ? if (usermsg != null && usermsg.length() > 0) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 如果消息是 bye,則斷開與此用戶的連接 并 告知所有用戶當(dāng)前信息,跳出循環(huán)終止當(dāng)前進(jìn)程
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (secondMsg.equals("bye")) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? clients.remove(this);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? for (Client c : clients) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c.out.println(usermsg);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? taMsg.append("——客戶離開:" + nickname + "\n");
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新在線用戶數(shù)量 lstUsers的界面信息
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? updateUsers();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break;?
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? /**
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 每當(dāng)有新用戶連接時(shí),服務(wù)器就會(huì)接收到 USERS 請(qǐng)求
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 當(dāng)服務(wù)器接收到此請(qǐng)求時(shí),就會(huì)要求現(xiàn)在所有用戶更新 在線用戶數(shù)量 的列表
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* */
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (usermsg.equals("USERS")) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? updateUsers();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? // 當(dāng)用戶發(fā)出的消息都不是以上兩者時(shí),消息才會(huì)被正常發(fā)送
? ? ? ? ? ? ? ? ? ? ? ? ? ? for (Client c : clients) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c.out.println(usermsg);
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? socket.close();
? ? ? ? ? ? ? ? } catch (Exception ex) {
? ? ? ? ? ? ? ? ? ? System.out.println(ex);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
?
? ? ? ? ? ? // TODO 更新在線用戶數(shù)量 lstUsers 信息,并要求所有的用戶端同步更新
? ? ? ? ? ? public void updateUsers() {
? ? ? ? ? ? ? ? // clientNames 是 Vector<String>對(duì)象,用來存放所有用戶的名字
? ? ? ? ? ? ? ? clientNames.removeAllElements();
? ? ? ? ? ? ? ? StringBuffer allname = new StringBuffer();
? ? ? ? ? ? ? ? for (AcceptRunnable.Client client : clients) {
? ? ? ? ? ? ? ? ? ? clientNames.add(0, client.nickname);
? ? ? ? ? ? ? ? ? ? allname.insert(0, "|" + client.nickname);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? panDown.setBorder(new TitledBorder("在線用戶(" +clientNames.size() + "個(gè))"));
? ? ? ? ? ? ? ? // 要求所有的用戶端同步更新
? ? ? ? ? ? ? ? for (Client c : clients) {
? ? ? ? ? ? ? ? ? ? c.out.println(clientNames);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? lstUsers.setListData(clientNames);
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? // TODO 主方法
? ? public static void main(String[] args) {
? ? ? ? new Server();
? ? }
}

客戶端代碼:

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
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.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Vector;
?
?
public class Client extends JFrame { ? ? ?//客戶機(jī)窗體類
? ? // TODO 該圖形界面擁有四塊區(qū)域,分別位于上、左、中、下 (up、Left、middle、down)。
? ? private JPanel panUp = new JPanel();
? ? private JPanel panLeft = new JPanel();
? ? private JPanel panMid = new JPanel();
? ? private JPanel panDown = new JPanel();
?
? ? // panUp 區(qū)域的子節(jié)點(diǎn)定義,3個(gè)標(biāo)簽、3個(gè)輸入框、2個(gè)按鈕
? ? private JLabel lblLocalPort1 = new JLabel("服務(wù)器IP: ");
? ? private JLabel lblLocalPort2 = new JLabel("端口: ");
? ? private JLabel lblLocalPort3 = new JLabel("本人昵稱: ");
? ? protected JTextField tfLocalPort1 = new JTextField(15);
? ? protected JTextField tfLocalPort2 = new JTextField(5);
? ? protected JTextField tfLocalPort3 = new JTextField(5);
? ? protected JButton butStart = new JButton("連接服務(wù)器");
? ? protected JButton butStop = new JButton("斷開服務(wù)器");
? ? // TODO
?
? ? // panLeft 區(qū)域的子節(jié)點(diǎn)定義,顯示框、滾動(dòng)條
? ? protected JTextArea taMsg = new JTextArea(25, 25);
? ? JScrollPane scroll = new JScrollPane(taMsg);
?
? ? // panMid 區(qū)域的子節(jié)點(diǎn)定義,lstUsers在線用戶界面
? ? JList lstUsers = new JList();
?
? ? // panDown 區(qū)域的子節(jié)點(diǎn)定義,標(biāo)簽,輸入框
? ? private JLabel lblLocalPort4 = new JLabel("消息(按回車發(fā)送): ");
? ? protected JTextField tfLocalPort4 = new JTextField(20);
? ? /**
? ? ?* ===== 變量分割 =====
? ? ?* 上面是圖形界面變量,下面是存放數(shù)據(jù)的變量
? ? ?*/
? ? BufferedReader in;
? ? PrintStream out;
? ? public static int localPort = 8000; ? ? // 默認(rèn)端口
? ? public static String localIP = "127.0.0.1"; ? ? // 默認(rèn)服務(wù)器IP地址
? ? public static String nickname = "Cat"; ? ? ?// 默認(rèn)用戶名
? ? public Socket socket;
? ? public static String msg; ? ? ? // 存放本次發(fā)送的消息
? ? Vector<String> clientNames = new Vector<>();
?
? ? // TODO 構(gòu)造方法
? ? public Client() {
? ? ? ? init();
? ? }
?
? ? // TODO 初始化方法:初始化圖形界面
? ? private void init() {
? ? ? ? // panUp 區(qū)域初始化:流式面板,3個(gè)標(biāo)簽、3個(gè)輸入框,2個(gè)按鈕
? ? ? ? panUp.setLayout(new FlowLayout());
? ? ? ? panUp.add(lblLocalPort1);
? ? ? ? panUp.add(tfLocalPort1);
? ? ? ? panUp.add(lblLocalPort2);
? ? ? ? panUp.add(tfLocalPort2);
? ? ? ? panUp.add(lblLocalPort3);
? ? ? ? panUp.add(tfLocalPort3);
? ? ? ? tfLocalPort1.setText(localIP);
? ? ? ? tfLocalPort2.setText(String.valueOf(localPort));
? ? ? ? tfLocalPort3.setText(nickname);
? ? ? ? panUp.add(butStart);
? ? ? ? panUp.add(butStop);
? ? ? ? butStart.addActionListener(new linkServerHandlerStart());
? ? ? ? butStop.addActionListener(new linkServerHandlerStop());
? ? ? ? butStop.setEnabled(false); ? ? ?// 斷開服務(wù)器按鈕的初始狀態(tài)應(yīng)該為 不可點(diǎn)擊,只有連接服務(wù)器之后才能點(diǎn)擊
?
? ? ? ? // 添加 Left
? ? ? ? taMsg.setEditable(false);
? ? ? ? panLeft.add(scroll);
? ? ? ? panLeft.setBorder(new TitledBorder("聊天——消息區(qū)"));
? ? ? ? scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
? ? ? ? scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
?
? ? ? ? // 添加 Middle
? ? ? ? panMid.setBorder(new TitledBorder("在線用戶"));
? ? ? ? panMid.add(lstUsers);
? ? ? ? lstUsers.setVisibleRowCount(20);
?
? ? ? ? // 添加 Down
? ? ? ? // TODO 此處注意:JTextField輸入框 的回車事件默認(rèn)存在,無需添加
? ? ? ? panDown.setLayout(new FlowLayout());
? ? ? ? panDown.add(lblLocalPort4);
? ? ? ? panDown.add(tfLocalPort4);
? ? ? ? tfLocalPort4.addActionListener(new Client.SendHandler());
?
? ? ? ? // 圖形界面的總體初始化 + 啟動(dòng)圖形界面
? ? ? ? this.setTitle("客戶端");
? ? ? ? this.add(panUp, BorderLayout.NORTH);
? ? ? ? this.add(panLeft, BorderLayout.WEST);
? ? ? ? this.add(panMid, BorderLayout.CENTER);
? ? ? ? this.add(panDown, BorderLayout.SOUTH);
? ? ? ? this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
? ? ? ? this.addWindowListener(new WindowHandler());
? ? ? ? this.setPreferredSize(new Dimension(800, 600));
? ? ? ? this.pack();
? ? ? ? this.setVisible(true);
? ? }
?
? ? // TODO “連接服務(wù)器”按鈕的動(dòng)作事件監(jiān)聽處理類:
? ? private class linkServerHandlerStart implements ActionListener {
? ? ? ? @Override
? ? ? ? public void actionPerformed(ActionEvent e) {
? ? ? ? ? ? // 當(dāng)點(diǎn)擊"連接服務(wù)器"按鈕之后,該按鈕被禁用(不可重復(fù)點(diǎn)擊)。同時(shí)"斷開服務(wù)器按鈕"被恢復(fù)使用
? ? ? ? ? ? butStart.setEnabled(false);
? ? ? ? ? ? butStop.setEnabled(true);
? ? ? ? ? ? localIP = tfLocalPort1.getText();
? ? ? ? ? ? localPort = Integer.parseInt(tfLocalPort2.getText());
? ? ? ? ? ? nickname = tfLocalPort3.getText();
? ? ? ? ? ? linkServer(); ? // 連接服務(wù)器
? ? ? ? ? ? Thread acceptThread = new Thread(new Client.ReceiveRunnable());
? ? ? ? ? ? acceptThread.start();
? ? ? ? }
? ? }
?
? ? // TODO “斷開服務(wù)器”按鈕的動(dòng)作事件監(jiān)聽處理類
? ? private class linkServerHandlerStop implements ActionListener {
? ? ? ? /**
? ? ? ? ?* 當(dāng)點(diǎn)擊該按鈕之后,斷開服務(wù)器連接、清空?qǐng)D形界面所有數(shù)據(jù)
? ? ? ? ?*/
? ? ? ? @Override
? ? ? ? public void actionPerformed(ActionEvent e) {
? ? ? ? ? ? taMsg.setText("");
? ? ? ? ? ? clientNames = new Vector<>();
? ? ? ? ? ? updateUsers();
? ? ? ? ? ? out.println("——客戶【" + nickname + "】離開:bye\n");
? ? ? ? ? ? butStart.setEnabled(true);
? ? ? ? ? ? butStop.setEnabled(false);
? ? ? ? }
? ? }
?
? ? // TODO 連接服務(wù)器的方法
? ? public void linkServer() {
? ? ? ? try {
? ? ? ? ? ? socket = new Socket(localIP, localPort);
? ? ? ? } catch (Exception ex) {
? ? ? ? ? ? taMsg.append("==== 連接服務(wù)器失敗~ ====");
? ? ? ? }
? ? }
?
? ? // TODO 接收服務(wù)器消息的線程關(guān)聯(lián)類
? ? private class ReceiveRunnable implements Runnable {
? ? ? ? public void run() {
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
? ? ? ? ? ? ? ? out = new PrintStream(socket.getOutputStream());
? ? ? ? ? ? ? ? out.println(nickname); ? ? ?// 當(dāng)用戶首次連接服務(wù)器時(shí),應(yīng)該向服務(wù)器發(fā)送自己的用戶名、方便服務(wù)器區(qū)分
? ? ? ? ? ? ? ? taMsg.append("——本人【" + nickname + "】成功連接到服務(wù)器......\n");
? ? ? ? ? ? ? ? out.println("USERS"); ? ? ? // 向服務(wù)器發(fā)送"神秘代碼",請(qǐng)求 當(dāng)前在線用戶 列表
? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? msg = in.readLine(); ? ? ? // 讀取服務(wù)器端的發(fā)送的數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? // 此 if 語句的作用是:過濾服務(wù)器發(fā)送過來的 更新當(dāng)前在線用戶列表 請(qǐng)求
? ? ? ? ? ? ? ? ? ? if (msg.matches(".*\\[.*\\].*")) {
? ? ? ? ? ? ? ? ? ? ? ? clientNames.removeAllElements();
? ? ? ? ? ? ? ? ? ? ? ? String[] split = msg.split(",");
? ? ? ? ? ? ? ? ? ? ? ? for (String single : split) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? clientNames.add(single);
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? updateUsers();
? ? ? ? ? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? // 更新 "聊天——消息區(qū)" 信息
? ? ? ? ? ? ? ? ? ? taMsg.append(msg + "\n");
?
? ? ? ? ? ? ? ? ? ? // 此 if 語句作用:與服務(wù)器進(jìn)行握手確認(rèn)消息。
? ? ? ? ? ? ? ? ? ? // 當(dāng)接收到服務(wù)器端發(fā)送的確認(rèn)離開請(qǐng)求bye 的時(shí)候,用戶真正離線
? ? ? ? ? ? ? ? ? ? msg = msg.substring(msg.lastIndexOf(":") + 1);
? ? ? ? ? ? ? ? ? ? if (msg.equals(nickname)) {
? ? ? ? ? ? ? ? ? ? ? ? socket.close();
? ? ? ? ? ? ? ? ? ? ? ? clientNames.remove(nickname);
? ? ? ? ? ? ? ? ? ? ? ? updateUsers();
? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? // 終止線程
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? // TODO "發(fā)送消息文本框" 的動(dòng)作事件監(jiān)聽處理類
? ? private class SendHandler implements ActionListener {
? ? ? ? @Override
? ? ? ? public void actionPerformed(ActionEvent e) {
? ? ? ? ? ? out.println("【" + nickname + "】:" + tfLocalPort4.getText());
? ? ? ? ? ? tfLocalPort4.setText(""); ? ? ? // 當(dāng)按下回車發(fā)送消息之后,輸入框應(yīng)該被清空
? ? ? ? }
? ? }
?
? ? // TODO 窗口關(guān)閉的動(dòng)作事件監(jiān)聽處理類
? ? // 當(dāng)用戶點(diǎn)擊 "x" 離開窗口時(shí),也會(huì)向服務(wù)器發(fā)送 bye 請(qǐng)求,目的是為了同步更新數(shù)據(jù)。
? ? private class WindowHandler extends WindowAdapter {
? ? ? ? @Override
? ? ? ? public void windowClosing(WindowEvent e) {
? ? ? ? ? ? cutServer();
? ? ? ? }
? ? }
?
? ? private void cutServer() {
? ? ? ? out.println("——客戶【" + nickname + "】離開:bye");
? ? }
?
? ? // TODO 更新 "在線用戶列表" 的方法
? ? public void updateUsers() {
? ? ? ? panMid.setBorder(new TitledBorder("在線用戶(" + clientNames.size() + "個(gè))"));
? ? ? ? lstUsers.setListData(clientNames);
? ? }
?
? ? // TODO 主方法
? ? public static void main(String[] args) {
? ? ? ? new Client();
? ? }
}

如何同時(shí)開啟兩個(gè)客戶端進(jìn)行聊天?

將上述的 Client 類復(fù)制一份,改名為 Client2 ,然后同時(shí)啟動(dòng) Client 和 Client2 程序。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 記一次springboot中用undertow的坑

    記一次springboot中用undertow的坑

    這篇文章主要介紹了記一次springboot中用undertow的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • mybatis?mapper.xml?注釋帶參數(shù)的坑及解決

    mybatis?mapper.xml?注釋帶參數(shù)的坑及解決

    這篇文章主要介紹了mybatis?mapper.xml?注釋帶參數(shù)的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • spring boot使用thymeleaf模板的方法詳解

    spring boot使用thymeleaf模板的方法詳解

    thymeleaf 是新一代的模板引擎,在spring4.0中推薦使用thymeleaf來做前端模版引擎。下面這篇文章主要給大家介紹了關(guān)于spring boot使用thymeleaf模板的方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面來一起看看吧。
    2017-07-07
  • java刪除指定目錄下指定格式文件的方法

    java刪除指定目錄下指定格式文件的方法

    這篇文章主要為大家詳細(xì)介紹了java刪除指定目錄下指定格式文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • SpringBoot 文件或圖片上傳與下載功能的實(shí)現(xiàn)

    SpringBoot 文件或圖片上傳與下載功能的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot 文件或圖片上傳與下載功能的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Java運(yùn)算符的知識(shí)點(diǎn)與代碼匯總

    Java運(yùn)算符的知識(shí)點(diǎn)與代碼匯總

    這篇文章主要給大家總結(jié)介紹了關(guān)于Java運(yùn)算符知識(shí)點(diǎn)與代碼的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java的MyBatis框架中XML映射緩存的使用教程

    Java的MyBatis框架中XML映射緩存的使用教程

    MyBatis程序在做好XML映射后能夠有緩存的功能,這樣映射過SQL語句的配置以后就可以拿過來直接用了,這里我們來一起總結(jié)一下Java的MyBatis框架中XML映射緩存的使用教程
    2016-06-06
  • Spring項(xiàng)目XML文件使用小結(jié)

    Spring項(xiàng)目XML文件使用小結(jié)

    這篇文章主要介紹了Spring項(xiàng)目XML文件使用常見介紹,主要包括項(xiàng)目pom文件,項(xiàng)目初始IOC容器及項(xiàng)目需要自動(dòng)裝配的代碼詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Java實(shí)現(xiàn)基本排序算法的示例代碼

    Java實(shí)現(xiàn)基本排序算法的示例代碼

    排序就是將一串記錄按照其中某個(gè)或某些關(guān)鍵字的大小,遞增或遞減的排列起來的操作。本文將用Java實(shí)現(xiàn)一些基本的排序算法,感興趣的可以了解一下
    2022-07-07
  • SpringBoot如何上傳圖片

    SpringBoot如何上傳圖片

    這篇文章主要介紹了SpringBoot如何上傳圖片,幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下
    2020-09-09

最新評(píng)論