日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

JavaSE简单实现多线程聊天

發(fā)布時間:2023/12/10 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaSE简单实现多线程聊天 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.1 主程序入口

在主程序入口處,通過設(shè)置MyWindow的第一個參數(shù),如果為true則為服務(wù)器,如果為false,則為客戶端,當然也可以設(shè)置第二個參數(shù),區(qū)分客戶端和服務(wù)器的窗口標題。

public class JavaMain {public static void main(String[] args) {MyWindow w=new MyWindow(false,"QQ聊天"); ?//運行時將false改成true,?先啟動服務(wù)端,然后再改成false啟動客戶端w.setNet("192.168.1.103", 12345);} }

1.2 界面程序

界面程序根據(jù)主程序傳來的參數(shù)不同而創(chuàng)建客戶端和服務(wù)器窗口,根據(jù)界面的構(gòu)造函數(shù)中第一個參數(shù),isServer設(shè)置服務(wù)器窗體或者是客戶端窗體。

public class MyWindow extends JFrame {private static final long serialVersionUID = 1L;// 定義一個成員變量Client myClient = null;Server myServer=null;JTextArea area=null;// 設(shè)置默認的IP地址和端口private String ipAddress="127.0.0.1";private int nPort=50000;private boolean isServer=false;// 構(gòu)造函數(shù)public MyWindow(boolean isServer,String title) {this.isServer=isServer;setTitle(title);setSize(300, 400);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setLayout(null);initComponents();setVisible(true);}// 為外界提供設(shè)置IP地址和端口的方法public void setNet(String ip,int port){ipAddress=ip;nPort=port;// 對通信接口初始化 initCommication();}// 通過構(gòu)造函數(shù),將端口和文本顯示區(qū)傳遞給myServer對象public void initCommication(){if (isServer) {myServer=new Server(nPort,area);}else{myClient=new Client(ipAddress,nPort,area);}}public void initComponents() {// 添加一個文本區(qū)area = new JTextArea();area.setBounds(10, 20, 260, 200);add(area);// 添加一個文本框final JTextField text = new JTextField();text.setBounds(10, 240, 260, 30);add(text);// 添加一個發(fā)送按鈕JButton button = new JButton("發(fā)送");button.setBounds(10, 290, 80, 30);button.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (isServer) {myServer.sendServerMsg(text.getText());}else{myClient.sendMsg(text.getText());}}});add(button);} }

1.3 服務(wù)器類

服務(wù)器類比較復(fù)雜,這里用到了內(nèi)部類,內(nèi)部類的好處就是能隨時訪問外部類的成員和方法,而無需通過傳參數(shù)的方法達到目的。

// 監(jiān)聽主線程 public class Server extends Thread {// 服務(wù)器Socketprivate ServerSocket serverSocket = null;private ArrayList<ServerThread> clientList = null;// 顯示區(qū)private JTextArea jTextArea = null;// 構(gòu)造函數(shù)public Server(int port, JTextArea area) {jTextArea = area;try {// 開始綁定端口serverSocket = new ServerSocket(port);// 初始化客戶端連接的列表clientList = new ArrayList<ServerThread>();} catch (IOException e) {System.err.println("服務(wù)器端口初始化失敗!\n");}jTextArea.setText("服務(wù)器成功啟動,等待客戶連接!\n");start(); // 啟動線程 }public void sendServerMsg(String msg) {jTextArea.append(msg + "\n");for (int i = clientList.size() - 1; i >= 0; i--) {clientList.get(i).getWriter().println("服務(wù)器:" + msg);clientList.get(i).getWriter().flush();}}// 線程程序public void run() {while (true) {try {// 用阻塞的方式,等待用戶連接請求Socket socket = serverSocket.accept();// 啟動一條為客戶端服務(wù)的線程ServerThread svthread = new ServerThread(socket);svthread.start();// 將該客戶加入列表中 clientList.add(svthread);} catch (IOException e) {e.printStackTrace();}}}// 服務(wù)線程(內(nèi)部類),用于處理客戶端的服務(wù)線程class ServerThread extends Thread {// 當前正在連接的SocketSocket socket = null;// 當前連接的Socket的輸入和輸出流(數(shù)據(jù)出入口)private PrintWriter writer = null;private BufferedReader reader = null;// 構(gòu)造函數(shù)public ServerThread(Socket s) {socket = s;try {// 獲取輸入輸出流reader = new BufferedReader(new InputStreamReader(s.getInputStream()));writer = new PrintWriter(s.getOutputStream());// 在此可以寫接收用戶端的信息,解析出來(IP地址) } catch (Exception e) {e.printStackTrace();}}// 獲得輸入流,供外界調(diào)用public BufferedReader getReader() {return reader;}// 獲得輸出流,供外界調(diào)用public PrintWriter getWriter() {return writer;}// 獲得socketpublic Socket getSocket() {return socket;}// 線程服務(wù)程序public void run() {// 創(chuàng)建一個變量,用于接收客戶端發(fā)來的信息String message = null;while (true) {try {// 讀取輸入流message = reader.readLine();// 如果是下線命令if (message.equals("Bye")) {// 在客戶端列表上刪除該用戶ServerThread temp = null;for (int i = clientList.size() - 1; i >= 0; i--) {temp = clientList.get(i);if (temp.getSocket().equals(socket)) {clientList.remove(i);}temp.stop();}// 斷開連接釋放資源 reader.close();writer.close();socket.close();return;} else {// 在文本區(qū)顯示該消息jTextArea.append(message + "\n");// 將該消息廣播給其他用戶 broadcastMsg(message);}} catch (Exception e) {// TODO: handle exception }}}// 廣播消息public void broadcastMsg(String msg) {for (int i = clientList.size() - 1; i >= 0; i--) {clientList.get(i).getWriter().println(msg);clientList.get(i).getWriter().flush();}}} }

1.4 客戶端類

客戶端類比較簡單,只要創(chuàng)建一個線程,與服務(wù)器連接即可。

public class Client extends Thread {// 寫該類的成員變量private Socket socket=null;private PrintWriter out=null;private BufferedReader in=null;private JTextArea area;// 寫構(gòu)造函數(shù),完成初始化public Client(String ip,int nPort,JTextArea area){try {socket=new Socket(ip, nPort);} catch (UnknownHostException e) {System.err.println("初始化失敗!");} catch (IOException e) {System.err.println("初始化失敗!");}start(); // 啟動線程,讓線程開始工作this.area=area;this.area.setText("初始化成功,連接上服務(wù)器!\n");}// 發(fā)送消息public void sendMsg(String msg){if(socket.isConnected()==true){out.println("客戶端:"+msg);out.flush();// 將消息推送給客戶端 }}public void run(){while(true){try {// 獲取客戶端的輸入流InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);in = new BufferedReader(isr);// 獲取客戶端的輸出流out = new PrintWriter(socket.getOutputStream(), true);while(true){// 不停的讀取從服務(wù)器發(fā)來的信息String info = in.readLine();area.append(info + "\n");}} catch (Exception e) {System.err.println("發(fā)生數(shù)據(jù)流讀取錯誤,程序退出!");System.exit(1);}finally{try {// 結(jié)束,掃尾工作 out.close();in.close();socket.close();} catch (Exception e2) {}}}} }

1.5 運行結(jié)果

運行結(jié)果如下所示:

?

轉(zhuǎn)載于:https://www.cnblogs.com/StanLong/p/6781132.html

總結(jié)

以上是生活随笔為你收集整理的JavaSE简单实现多线程聊天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。