国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

Java簡(jiǎn)單聊天室

2019-11-15 01:13:51
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
java簡(jiǎn)單聊天室

實(shí)現(xiàn)Java簡(jiǎn)單的聊天室

  所用主要知識(shí):多線程+網(wǎng)絡(luò)編程

    效果如下圖

/** * * @author Administrator * *簡(jiǎn)單的多人聊天系統(tǒng)——重點(diǎn):同時(shí)性,異步性 *1、客戶端:發(fā)送消息,并且接收消息 *1.1 消息發(fā)送至服務(wù)器:服務(wù)器每次都將客戶發(fā)過(guò)來(lái)的信息發(fā)送到每個(gè)客戶端 *1.2 接收消息:發(fā)送的同時(shí)也要接收消息,所以必須有兩個(gè)線程,一個(gè)發(fā)送消息,一個(gè)接收消息 *1.3 關(guān)于這兩個(gè)線程:如果沒(méi)有線程,接收和發(fā)送就是按順序執(zhí)行的了,那么是發(fā)送后接收還是接收后發(fā)送?或者是 *一邊可以發(fā)送一邊又可以接收呢?答案不言而喻 *1.4 在客戶端,用可以通過(guò)界面的點(diǎn)擊按鈕事件發(fā)送消息,所以就要開啟一個(gè)線程來(lái)接收服務(wù)器發(fā)送給客戶端的消息了 *1.5 多線程:不需按步驟逐步循環(huán),可以和其他程序同時(shí)執(zhí)行,不相互干擾 *2、服務(wù)器端:接收所有用戶的消息并且借每個(gè)用戶的消息發(fā)送給連接了服務(wù)器的客戶端 *2.1服務(wù)器既要接收C端信息又要想所有C端發(fā)送信息,先收后發(fā)。一收就發(fā)。 *2.2S端還要顯示C端上線提醒 *2.3上線提醒和收發(fā)信息是不影響的,互不干擾的,但是都要在S端上執(zhí)行,如果沒(méi)有線程,所以的程序都要按順序執(zhí)行了所以又要 多線程 *2.4一個(gè)線程負(fù)責(zé)向所以C端發(fā)送接收到的任何一條信息,一個(gè)線程負(fù)責(zé)顯示C端上線的信息 * *3、類:S端:Server、ServerFrame、sendThread 三個(gè)類 * C端:Client、ClientFrame 兩個(gè)類 * */

  1 package com.java.chat;  2   3 import java.awt.event.ActionEvent;  4 import java.awt.event.ActionListener;  5 import java.io.BufferedReader;  6 import java.io.BufferedWriter;  7 import java.io.IOException;  8 import java.io.InputStream;  9 import java.io.InputStreamReader; 10 import java.io.OutputStream; 11 import java.io.OutputStreamWriter; 12 import java.net.ServerSocket; 13 import java.net.Socket; 14 import java.util.ArrayList; 15 import java.util.List; 16  17 import javax.swing.JButton; 18 import javax.swing.JFrame; 19 import javax.swing.JTextArea; 20  21  22 public class Server { 23     //用于保存Socket的集合,也可以說(shuō)是把個(gè)C端與S端的一個(gè)連接通道保存起來(lái) 24     //作用:服務(wù)器將接收到的信息發(fā)給集合里的所以socket,也就是發(fā)給每個(gè)C端 25     public static List<Socket> list = new ArrayList<Socket>(); 26  27     public static void main(String[] args) { 28         new ServerFrame("服務(wù)器端"); 29     } 30  31 } 32  33 /* 34  * 繼承Jframe類表示該類可以創(chuàng)建一個(gè)窗口程序了, 35  * 實(shí)現(xiàn)ActionListener:動(dòng)作監(jiān)聽,在S端點(diǎn)擊“啟動(dòng)服務(wù)器”是要執(zhí)行的代碼 36  * 實(shí)現(xiàn)Runnable:實(shí)現(xiàn)多線程,該窗口是個(gè)客戶端窗口,要開啟一個(gè)線程接收顯示服務(wù)器發(fā)過(guò)來(lái)的信息 37  */ 38 class ServerFrame extends JFrame implements ActionListener, Runnable { 39  40     PRivate static final long serialVersionUID = 1L; 41  42     private ServerSocket serverSocket = null; 43  44     private Socket socket; 45  46     private JButton start; 47     private JTextArea message; 48  49     public ServerFrame(String name) { 50         super(name); 51  52         start = new JButton("啟動(dòng)服務(wù)器"); 53         start.addActionListener(this); 54         message = new JTextArea(); 55         message.setEditable(false); 56         this.add(start, "North"); 57         this.add(message, "Center"); 58  59         this.setResizable(false); 60         this.setBounds(0, 0, 400, 300); 61         this.setVisible(true); 62         this.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE); 63     } 64  65     @Override 66     public void actionPerformed(ActionEvent e) { 67         if (e.getSource() == start) { 68             // 如果點(diǎn)擊的按鈕是開始按鈕。則啟動(dòng)服務(wù)器。 69             try { 70                 serverSocket = new ServerSocket(6666); 71                 message.setText("服務(wù)器已啟動(dòng)。。。"); 72                  73                 //單擊“啟動(dòng)服務(wù)器”開啟一個(gè)線程用于獲取用戶上線的情況 74                 new Thread(this).start(); 75                  76             } catch (IOException e1) { 77                 e1.printStackTrace(); 78             } 79         } 80     } 81  82     //獲取C端上線的情況 83     @Override 84     public void run() { 85         String address = null; 86         int port = 0; 87         //用一個(gè)死循環(huán)一直讓S端開啟接收C端的連接,將C端的ip和端口顯示在面板上 88         //如果用循環(huán)的話就只能接收一次 89         while (true) { 90             try { 91                 socket = serverSocket.accept(); 92                 Server.list.add(socket); 93                 address = socket.getInetAddress().getHostAddress(); 94                 port = socket.getPort(); 95                 message.append("/r/nip/" + address + ":" + port + "/t上線了"); 96                  97                 //開啟轉(zhuǎn)發(fā)信息的線程 98                 new sendThread(socket).start(); 99 100             } catch (IOException e) {101 //                System.out.println(address + ":" + port + "/t退出了服務(wù)器");102             }103         }104     }105 106 }107 108 /*109  * 接收每個(gè)C端的信息并向每個(gè)C端發(fā)送接收到的信息110  */111 class sendThread extends Thread {112     private Socket socket;113 114     public sendThread(Socket socket) {115         super();116         this.socket = socket;117     }118 119     @Override120     public void run() {121         InputStream is = null;122         BufferedReader br = null;123         String str = null;124         OutputStream os = null;125         BufferedWriter bw = null;126         while (true) {127             try {128                 is = socket.getInputStream();129                 br = new BufferedReader(new InputStreamReader(is));130                 str = br.readLine();131                 for (Socket s : Server.list) {132                     os = s.getOutputStream();133                     bw = new BufferedWriter(new OutputStreamWriter(os));134                     bw.write(str);135                     bw.newLine();136                     bw.flush();137                 }138             } catch (IOException e) {139                 //如果斷開連接則移除對(duì)于的socket140                 Server.list.remove(socket);141             }142         }143     }144 }
服務(wù)器端代碼
  1 package com.java.chat;  2   3 import java.awt.BorderLayout;  4 import java.awt.Color;  5 import java.awt.Font;  6 import java.awt.event.ActionEvent;  7 import java.awt.event.ActionListener;  8 import java.io.BufferedReader;  9 import java.io.BufferedWriter; 10 import java.io.IOException; 11 import java.io.InputStream; 12 import java.io.InputStreamReader; 13 import java.io.OutputStream; 14 import java.io.OutputStreamWriter; 15 import java.net.Socket; 16 import java.text.SimpleDateFormat; 17 import java.util.Date; 18  19 import javax.swing.JButton; 20 import javax.swing.JFrame; 21 import javax.swing.JLabel; 22 import javax.swing.JOptionPane; 23 import javax.swing.JPanel; 24 import javax.swing.JScrollPane; 25 import javax.swing.JTextArea; 26 import javax.swing.JTextField; 27  28 /** 29  *  30  * @author Administrator 31  * 32  */ 33  34 public class Client { 35     public static void main(String[] args) { 36         new ClientFrame("客戶端"); 37     } 38 } 39  40 /* 41  * 繼承Jframe類表示該類可以創(chuàng)建一個(gè)窗口程序了, 42  * 實(shí)現(xiàn)ActionListener:動(dòng)作監(jiān)聽,就是一個(gè)事件發(fā)送后應(yīng)該執(zhí)行什么就要重新它的方法 43  * 實(shí)現(xiàn)Runnable:實(shí)現(xiàn)多線程,該窗口是個(gè)客戶端窗口,要開啟一個(gè)線程接收顯示服務(wù)器發(fā)過(guò)來(lái)的信息 44  */ 45 class ClientFrame extends JFrame implements ActionListener, Runnable { 46  47     private static final long serialVersionUID = 1L; 48  49     private Socket socket; 50     OutputStream os = null; 51     BufferedWriter bw = null; 52      53     JTextArea message; 54     JScrollPane scroll; 55     JTextField input; 56     JButton submit; 57     JPanel panel; 58  59     String uname = ""; 60     // 聊天頁(yè)面 61     JPanel chat; 62  63     // 登錄頁(yè)面 64     JPanel login; 65     JTextField username; 66     JButton ok; 67  68     public ClientFrame(String name) { 69         super(name); 70      71         message = new JTextArea(); 72         message.setEditable(false); 73         scroll = new JScrollPane(message); 74         input = new JTextField(20); 75         submit = new JButton("發(fā)送"); 76         panel = new JPanel(); 77  78         panel.add(input); 79         panel.add(submit); 80         chat = new JPanel(new BorderLayout()); 81         chat.add(scroll, "Center"); 82         chat.add(panel, "South"); 83          84          85         // 在創(chuàng)建客戶端窗體是就要把客戶端與服務(wù)端連接 86         try { 87             //127.0.0.1表示本機(jī)地址,地址好端口都可以改,這要看服務(wù)器那邊是什么地址和端口 88             socket = new Socket("127.0.0.1", 6666); 89             os = socket.getOutputStream(); 90             bw = new BufferedWriter(new OutputStreamWriter(os)); 91              92         } catch (IOException e1) { 93             e1.printStackTrace(); 94         } 95          96         /*    在創(chuàng)建C端窗體的時(shí)候也應(yīng)該開啟一個(gè)線程接收顯示來(lái)自服務(wù)器的信息 97          *     為什么要開啟一個(gè)線程呢?因?yàn)樵谶@個(gè)窗體里既要實(shí)現(xiàn)消息的發(fā)送, 98          *     也要接收信息,而且兩個(gè)不能按順序進(jìn)行,也互不干擾,所以開啟一個(gè)線程時(shí)時(shí)刻刻等著S端發(fā)來(lái)的信息 99          */100         //接收信息101         new Thread(this).start();102         103         //提交按鈕工作監(jiān)聽器,點(diǎn)擊提交時(shí)觸發(fā)104         submit.addActionListener(this);105 106         login = new JPanel();107         username = new JTextField(20);108         ok = new JButton("確定");109         ok.addActionListener(this);110         JLabel label = new JLabel("請(qǐng)輸入用戶名");111         label.setFont(new Font(Font.DIALOG, Font.BOLD, 28));112         label.setForeground(Color.red);113         login.add(label);114         login.add(username);115         login.add(ok);116 117         this.add(chat);118         this.add(login);119 120         this.setResizable(false);121         this.setBounds(400, 100, 400, 300);122         this.setVisible(true);123         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);124     }125 126     @Override127     public void actionPerformed(ActionEvent e) {128         if (e.getSource() == submit) {129             // 如果點(diǎn)擊提交按鈕,則表示需要將信息發(fā)送出去。130             String str = null;131             //以下三行是創(chuàng)建發(fā)送時(shí)間的代碼132             Date date = new Date();133             SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");134             String dateStr = format.format(date);135             136             str = uname+" "+dateStr+"  "+input.getText();137             138             try {139                 bw.write(str);140                 bw.newLine();141 //                System.out.println("客戶端發(fā)送了:"+str);142                 bw.flush();143             } catch (IOException e1) {144                 System.out.println("無(wú)法發(fā)送,服務(wù)器連接異常!");145             }146             147 //            System.out.println(str);148             149         } else if (e.getSource() == ok) {// 用戶登錄150             uname = username.getText();// 獲取文本框輸入的文本信息151             if ("".equals(uname)) {152                 JOptionPane.showMessageDialog(this, "用戶名不能為空!");153             } else {154                 login.setVisible(false);155                 chat.setVisible(true);156                 this.setTitle(uname + " 的客戶端");157                 this.add(chat);158             }159         }160     }161 162     //run方法里面的是接受S端信息和將信息顯示的代碼163     @Override164     public void run() {165         BufferedReader br = null;166         InputStream is = null;167         String str = null;168         try {169             is = socket.getInputStream();170             br = new BufferedReader(new InputStreamReader(is));171             while (true) {172                 str = br.readLine()+"/r/n";173                 message.append(str);174             }175         } catch (IOException e) {176             System.out.println("無(wú)法發(fā)送,服務(wù)器連接異常!");177         }178     }179 180 }
客戶端代碼

(完)


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广汉市| 南溪县| 汶上县| 贵定县| 灯塔市| 遂溪县| 沅陵县| 肇东市| 晋中市| 永嘉县| 仁寿县| 靖州| 宿松县| 普格县| 鄂伦春自治旗| 威远县| 永平县| 久治县| 南开区| 城步| 长寿区| 阜南县| 临清市| 惠东县| 旌德县| 卓资县| 西城区| 南宁市| 白水县| 吉木萨尔县| 安西县| 磐安县| 揭西县| 清水县| 肃北| 华蓥市| 潜山县| 江陵县| 东兴市| 阳新县| 庄河市|