Cyh的博客

          Email:kissyan4916@163.com
          posts - 26, comments - 19, trackbacks - 0, articles - 220

          網(wǎng)絡(luò)編程>>聊天室客戶端

          Posted on 2009-12-18 21:56 啥都寫點(diǎn) 閱讀(444) 評論(0)  編輯  收藏 所屬分類: J2SE
             客戶端通過Socket連接聊天室服務(wù)器的端口,然后獲得Socket的 輸入和輸出,往輸入流中寫自己的連接信息,包括IP地址和賬戶。
             客戶端連接服務(wù)器后,啟動一個線程專門去接受服務(wù)器端發(fā)送的信息
             使用StringTokenizer分析收到的信息,信息類型主要有:聊天信息、聊天室成員信息和服務(wù)器退出信息。

          import java.awt.BorderLayout;
          import java.awt.Color;
          import java.awt.FlowLayout;
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;
          import java.awt.event.WindowEvent;
          import java.io.BufferedReader;
          import java.io.IOException;
          import java.io.InputStreamReader;
          import java.io.PrintStream;
          import java.net.InetAddress;
          import java.net.Socket;
          import java.util.StringTokenizer;

          import javax.swing.BorderFactory;
          import javax.swing.JButton;
          import javax.swing.JFrame;
          import javax.swing.JLabel;
          import javax.swing.JPanel;
          import javax.swing.JScrollPane;
          import javax.swing.JTextArea;
          import javax.swing.JTextField;
          import javax.swing.SwingUtilities;
          import javax.swing.UIManager;
          import javax.swing.border.TitledBorder;

          /**
           * 聊天室的客戶端程序,GUI界面。
           
          */

          public class ChatClient extends JFrame implements ActionListener{
              
              
          // 登陸聊天室的名字標(biāo)簽和輸入框
              JLabel nameLabel = new JLabel();
              JTextField nameTextField 
          = new JTextField(15);

              
          // 連接和斷開連接的按鈕
              JButton connectButton = new JButton();
              JButton disConnectButton 
          = new JButton();

              
          // 聊天室內(nèi)容的文本域
              JTextArea chatContentTextArea = new JTextArea(930);

              
          // 發(fā)送消息的按鈕
              JButton sendMsgButton = new JButton();
              
          // 消息輸入框
              JTextField msgTextField = new JTextField(20);
              JLabel msglabel 
          = new JLabel();
              
          // 聊天室用戶列表
              java.awt.List peopleList = new java.awt.List(10);

              
          /*以下定義數(shù)據(jù)流和網(wǎng)絡(luò)變量*/
              Socket soc 
          = null
              PrintStream ps 
          = null
              
              
          // 客戶端偵聽服務(wù)器消息的線程
              ClentListener listener = null

              
          public ChatClient() {
                  init();
              }


              
          //    初始化圖形界面
              public void init() {

                  
          this.setTitle("聊天室客戶端");
                  
                  
          // 初始化按鈕和標(biāo)簽
                  nameLabel.setText("姓名:");
                  connectButton.setText(
          "連 接");
                  connectButton.addActionListener(
          this);
                  disConnectButton.setText(
          "斷 開");
                  disConnectButton.addActionListener(
          this);
                  
          // 設(shè)置聊天內(nèi)容不可編輯
                  chatContentTextArea.setEditable(false);
                  sendMsgButton.setText(
          "發(fā) 送");
                  sendMsgButton.addActionListener(
          this);
                  msgTextField.setText(
          "請輸入聊天信息");
                  
                  
          //panel1放置輸入姓名和連接兩個按鈕
                  JPanel panel1 = new JPanel();
                  panel1.setLayout(
          new FlowLayout());
                  panel1.add(nameLabel);
                  panel1.add(nameTextField);
                  panel1.add(connectButton);
                  panel1.add(disConnectButton);
                  
                  
          //用于放置聊天信息顯示和聊天人員列表
                  JPanel panel2 = new JPanel();
                  panel2.setLayout(
          new FlowLayout());
                  JScrollPane pane1 
          = new JScrollPane(chatContentTextArea);
                  pane1.setBorder(
          new TitledBorder(BorderFactory.createEtchedBorder(
                          Color.white, 
          new Color(134134134)), "聊天內(nèi)容"));
                  panel2.add(pane1);
                  JScrollPane pane2 
          = new JScrollPane(peopleList);
                  pane2.setBorder(
          new TitledBorder(BorderFactory.createEtchedBorder(
                          Color.white, 
          new Color(134134134)), "用戶列表"));
                  panel2.add(pane2);
                  
                  
          //用于放置發(fā)送信息區(qū)域
                  JPanel panel3 = new JPanel(); 
                  panel3.setLayout(
          new FlowLayout());
                  panel3.add(msglabel);
                  panel3.add(msgTextField);
                  panel3.add(sendMsgButton);
                  
                  
          // 將組件添加到界面
                  this.getContentPane().setLayout(new BorderLayout());
                  
          this.getContentPane().add(panel1, BorderLayout.NORTH);
                  
          this.getContentPane().add(panel2, BorderLayout.CENTER);
                  
          this.getContentPane().add(panel3, BorderLayout.SOUTH);
                  
                  
          this.pack();
                  
                  
          try {
                      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      SwingUtilities.updateComponentTreeUI(
          this);
                  }
           catch (Exception e) {
                      e.printStackTrace();
                  }

              }


              
          /**
               * 關(guān)閉聊天室客戶端事件
               
          */

              
          protected void processWindowEvent(WindowEvent e){
                  
          super.processWindowEvent(e);
                  
          if (e.getID() == WindowEvent.WINDOW_CLOSING) {
                      
          // 如果是關(guān)閉聊天室客戶端,則斷開連接
                      disconnect();
                      dispose();
                      System.exit(
          0);
                  }

              }

              
              
          /**
               * 處理按鈕事件
               
          */

              
          public void actionPerformed(ActionEvent event) {
                  Object source 
          = event.getSource();
                  
          if (source == connectButton){
                      
          // 如果點(diǎn)擊連接按鈕
                      if (soc == null{
                          
          try {
                              
          // 使用端口2525實(shí)例化一個本地套接字
                              soc = new Socket(InetAddress.getLocalHost(), Constants.SERVER_PORT); 
                              
          // 在控制臺打印實(shí)例化的結(jié)果
                              System.out.println(soc); 
                              
          //將ps指向soc的輸出流
                              ps = new PrintStream(soc.getOutputStream()); 
                              
          //定義一個字符緩沖存儲發(fā)送信息
                              StringBuffer info = new StringBuffer(Constants.CONNECT_IDENTIFER).append(Constants.SEPERATOR); 
                              
          //其中INFO為關(guān)鍵字讓服務(wù)器識別為連接信息
                              
          //并將name和ip用":"分開,在服務(wù)器端將用一個
                              
          //StringTokenizer類來讀取數(shù)據(jù)
                              String userinfo = nameTextField.getText() + Constants.SEPERATOR
                                      
          + InetAddress.getLocalHost().getHostAddress();
                              ps.println(info.append(userinfo));

                              ps.flush();
                              
          //將客戶端線程實(shí)例化,并啟動
                              listener = new ClentListener(this, nameTextField.getText(), soc);   
                              listener.start(); 
                          }
           catch (IOException e) {
                              System.out.println(
          "Error:" + e);
                              disconnect();
                          }

                      }

                      
                  }
           else if (source == disConnectButton){
                      
          // 如果點(diǎn)擊斷開連接按鈕
                      disconnect();
                      
                  }
           else if (source == sendMsgButton) {
                      
          //如果點(diǎn)擊發(fā)送按鈕
                      if (soc != null{
                           
          //定義并實(shí)例化一個字符緩沖存儲發(fā)送的聊天信息
                          StringBuffer msg = new StringBuffer(Constants.MSG_IDENTIFER).append(Constants.SEPERATOR);
                          
          //用打印流發(fā)送聊天信息
                          ps.println(msg.append(msgTextField.getText())); 
                          ps.flush();
                      }

                  }

              }


              
          /**
               * 斷開與服務(wù)器的連接
               
          */

              
          public void disconnect(){
                  
          if (soc != null{
                      
          try {
                          
          // 用打印流發(fā)送QUIT信息通知服務(wù)器斷開此次通信
                          ps.println(Constants.QUIT_IDENTIFER); 
                          ps.flush();
                          soc.close(); 
          //關(guān)閉套接字
                          listener.toStop();
                          soc 
          = null;
                      }
           catch (IOException e) {
                          System.out.println(
          "Error:" + e);
                      }
           
                  }

              }

              
              
          public static void main(String[] args){
                  ChatClient client 
          = new ChatClient();
                  client.setVisible(
          true);
              }


              
          /**
               * 客戶端線程類用來監(jiān)聽服務(wù)器傳來的信息
               
          */

              
          class ClentListener extends Thread    {
                  
          //存儲客戶端連接后的name信息
                  String name = null;
                  
          //客戶端接受服務(wù)器數(shù)據(jù)的輸入流
                  BufferedReader br = null;
                  
          //實(shí)現(xiàn)從客戶端發(fā)送數(shù)據(jù)到服務(wù)器的打印流
                  PrintStream ps = null;

                  
          //存儲客戶端的socket信息
                  Socket socket = null;
                  
          //存儲當(dāng)前運(yùn)行的ChatClient實(shí)例
                  ChatClient parent = null;

                  
          boolean running = true;

                  
          //構(gòu)造方法
                  public ClentListener(ChatClient p, String n, Socket s)    {

                      
          //接受參數(shù)
                      parent = p;
                      name 
          = n;
                      socket 
          = s;

                      
          try {
                          
          //實(shí)例化兩個數(shù)據(jù)流
                          br = new BufferedReader(new InputStreamReader(s
                                  .getInputStream()));
                          ps 
          = new PrintStream(s.getOutputStream());

                      }
           catch (IOException e) {
                          System.out.println(
          "Error:" + e);
                          parent.disconnect();
                      }

                  }
           
                  
                  
          // 停止偵聽
                  public void toStop(){
                      
          this.running = false;
                  }


                  
          //線程運(yùn)行方法
                  public void run(){
                      String msg 
          = null;
                      
          while (running) {
                          msg 
          = null;
                          
          try {
                              
          // 讀取從服務(wù)器傳來的信息
                              msg = br.readLine();
                              System.out.println(
          "receive msg: " + msg);
                          }
           catch (IOException e) {
                              System.out.println(
          "Error:" + e);
                              parent.disconnect();
                          }

                          
          // 如果從服務(wù)器傳來的信息為空則斷開此次連接
                          if (msg == null{
                              parent.listener 
          = null;
                              parent.soc 
          = null;
                              parent.peopleList.removeAll();
                              running 
          = false;
                              
          return;
                          }

                          
                          
          //用StringTokenizer類來實(shí)現(xiàn)讀取分段字符
                          StringTokenizer st = new StringTokenizer(msg, Constants.SEPERATOR); 
                          
          //讀取信息頭即關(guān)鍵字用來識別是何種信息
                          String keyword = st.nextToken(); 

                          
          if (keyword.equals(Constants.PEOPLE_IDENTIFER)) {
                              
          //如果是PEOPLE則是服務(wù)器發(fā)來的客戶連接信息
                              
          //主要用來刷新客戶端的用戶列表
                              parent.peopleList.removeAll();
                              
          //遍歷st取得目前所連接的客戶
                              while (st.hasMoreTokens())     {
                                  String str 
          = st.nextToken();
                                  parent.peopleList.add(str);
                              }

                              
                          }
           else if (keyword.equals(Constants.MSG_IDENTIFER)) {
                              
          //如果關(guān)鍵字是MSG則是服務(wù)器傳來的聊天信息, 
                              
          //主要用來刷新客戶端聊天信息區(qū)將每個客戶的聊天內(nèi)容顯示出來
                              String usr = st.nextToken();
                              parent.chatContentTextArea.append(usr);
                              parent.chatContentTextArea.append(st.nextToken(
          "\0"));
                              parent.chatContentTextArea.append(
          "\r\n");
                              
                          }
           else if (keyword.equals(Constants.QUIT_IDENTIFER)) {
                              
          //如果關(guān)鍵字是QUIT則是服務(wù)器關(guān)閉的信息, 切斷此次連接
                              System.out.println("Quit");
                              
          try {
                                  running 
          = false;
                                  parent.listener 
          = null;
                                  parent.soc.close();
                                  parent.soc 
          = null;
                              }
           catch (IOException e) {
                                  System.out.println(
          "Error:" + e);
                              }
           finally {
                                  parent.soc 
          = null;
                                  parent.peopleList.removeAll();
                              }

                              
                              
          break;
                          }

                      }

                      
          //清除用戶列表
                      parent.peopleList.removeAll();
                  }

              }
           
          }
           


                                                                                                                 --    學(xué)海無涯
                  

          主站蜘蛛池模板: 田东县| 青冈县| 涪陵区| 仪陇县| 营山县| 大荔县| 桦甸市| 阜城县| 宁陕县| 临澧县| 辽阳县| 盐边县| 乐清市| 乐都县| 龙海市| 砀山县| 邻水| 白城市| 吕梁市| 汝阳县| 云南省| 建平县| 当雄县| 名山县| 若羌县| 晋中市| 海伦市| 漯河市| 城口县| 南岸区| 沂源县| 定南县| 永宁县| 龙门县| 上高县| 大理市| 新民市| 黔江区| 高尔夫| 清流县| 曲水县|