Quantcast
Channel: 英特尔开发人员专区文章
Viewing all articles
Browse latest Browse all 583

多线程实现聊天程序

$
0
0

客户端 ChatClient.java:

  1. package com.chat.client;  
  2.   
  3. import java.awt.BorderLayout;  
  4. import java.awt.Frame;  
  5. import java.awt.TextArea;  
  6. import java.awt.TextField;  
  7. import java.awt.event.ActionEvent;  
  8. import java.awt.event.ActionListener;  
  9. import java.awt.event.WindowAdapter;  
  10. import java.awt.event.WindowEvent;  
  11. import java.io.DataInputStream;  
  12. import java.io.DataOutputStream;  
  13. import java.io.IOException;  
  14. import java.net.Socket;  
  15. import java.net.UnknownHostException;  
  16. import java.text.SimpleDateFormat;  
  17. import java.util.Date;  
  18. /** 
  19.  * 聊天程序客户端 
  20.  * @author Tandaly 
  21.  * @date 2013-6-17 上午9:01:38 
  22.  */  
  23. public class ChatClient extends Frame  
  24. {  
  25.       
  26.     private static final long serialVersionUID = -4776932994542738425L;  
  27.       
  28.     private Socket socket = null;  
  29.     private DataOutputStream dos = null;  
  30.     private DataInputStream dis = null;  
  31.     private boolean bConnected = false;//是否连接上服务器 默认为否  
  32.     private Thread connThread = new Thread(new ConnectThread());  
  33.       
  34.     private TextField tfTxt = new TextField();//发送文本  
  35.     private TextArea taContent = new TextArea();//消息内容  
  36.       
  37.       
  38.     /** 
  39.      * 连接服务 
  40.      */  
  41.     public void connect()  
  42.     {  
  43.         try  
  44.         {  
  45.             this.socket = new Socket("127.0.0.1"9999);  
  46.             this.bConnected = true;//连接服务器成功  
  47.             this.dos = new DataOutputStream(this.socket.getOutputStream());  
  48.             this.dis = new DataInputStream(this.socket.getInputStream());  
  49.         } catch (UnknownHostException e)  
  50.         {  
  51.             System.out.println("SYSTEM:服务器地址有误!");  
  52.         } catch (IOException e)  
  53.         {  
  54.             System.out.println("SYSTEM:连接服务器失败!");  
  55.         }  
  56.     }  
  57.       
  58.     /** 
  59.      * 关闭连接 
  60.      */  
  61.     public void disConnect()  
  62.     {  
  63.         try  
  64.         {  
  65.             this.bConnected = false;//断开服务器连接  
  66.             if(null != this.dos)  
  67.                 this.dos.close();  
  68.             if(null != this.dis)  
  69.                 this.dis.close();  
  70.             if(null != this.socket)  
  71.                 this.socket.close();  
  72.         } catch (IOException e)  
  73.         {  
  74.             e.printStackTrace();  
  75.         }  
  76.     }  
  77.       
  78.     /** 
  79.      * 运行窗体 
  80.      */  
  81.     public void launchFrame()  
  82.     {  
  83.         setLocation(500100);//设置窗体位置  
  84.         setSize(400500);//设置窗体大小  
  85.           
  86.         //添加窗体元素  
  87.         this.add(tfTxt, BorderLayout.SOUTH);//添加发送文本  
  88.         this.add(taContent, BorderLayout.NORTH);//添加消息内容  
  89.           
  90.         pack();//去除空白  
  91.           
  92.         //添加一个窗口监听事件实现窗口关闭  
  93.         this.addWindowListener(new WindowAdapter()  
  94.         {  
  95.             @Override  
  96.             public void windowClosing(WindowEvent e)  
  97.             {  
  98.                 System.exit(0);//退出程序  
  99.             }  
  100.         });  
  101.           
  102.         tfTxt.addActionListener(new tfTxtListener());//添加发送文本回车监听  
  103.           
  104.         setVisible(true);//设置窗体可见  
  105.           
  106.         //connect();//连接服务器操作  
  107.           
  108.         connThread.start();  
  109.           
  110.         new Thread(new ReceiveMsgThread()).start();//启动接收消息线程  
  111.     }  
  112.       
  113.     /** 
  114.      * 入口函数 
  115.      * @param args 
  116.      */  
  117.     public static void main(String[] args)  
  118.     {  
  119.         new ChatClient().launchFrame();  
  120.     }  
  121.       
  122.     /** 
  123.      * 发送文本监听类 
  124.      * @author Tandaly 
  125.      * @date 2013-6-17 上午9:05:28 
  126.      */  
  127.     class tfTxtListener implements ActionListener  
  128.     {  
  129.         @Override  
  130.         public void actionPerformed(ActionEvent e)  
  131.         {  
  132.             String content = taContent.getText();  
  133.             String txt = tfTxt.getText().trim();  
  134.             if(bConnected)  
  135.             {  
  136.                 if(!"".equals(txt))  
  137.                 {  
  138.                     taContent.setText(content + "\n我 "  
  139.                             +new SimpleDateFormat("hh:MM:ss").format(new Date())+"\n  " + txt);  
  140.                     tfTxt.setText("");  
  141.                     try  
  142.                     {  
  143.                         dos.writeUTF(txt);//向服务端发送消息  
  144.                     } catch (IOException e1)  
  145.                     {  
  146.                         System.out.println("发送消息失败,请检查是否正确连接服务器!");  
  147.                         bConnected = false;  
  148.                     }  
  149.                 }  
  150.             } else  
  151.             {  
  152.                 taContent.setText(content + "\n系统消息  "  
  153.                         +new SimpleDateFormat("hh:MM:ss").format(new Date())  
  154.                         +"\n----发送消息失败,请检查服务器是否连接正常----");  
  155.                 tfTxt.setText("");  
  156.             }  
  157.         }  
  158.           
  159.     }  
  160.        
  161.     /** 
  162.      * 接受消息线程 
  163.      * @author Tandaly 
  164.      * @date 2013-6-17 上午10:01:55 
  165.      */  
  166.     private class ReceiveMsgThread implements Runnable  
  167.     {  
  168.   
  169.         @Override  
  170.         public void run()  
  171.         {  
  172.             while(bConnected)  
  173.             {  
  174.                 try  
  175.                 {  
  176.                     String receiveMsg = dis.readUTF();  
  177.                     String content = taContent.getText();  
  178.                     taContent.setText(content + "\n匿名 "  
  179.                             +new SimpleDateFormat("hh:MM:ss").format(new Date())+"\n   " + receiveMsg);  
  180.                 } catch (IOException e)  
  181.                 {  
  182.                     System.out.println("SYSTEM:接收消息失败,服务器未连接");  
  183.                 }  
  184.             }  
  185.         }  
  186.           
  187.     }  
  188.       
  189.       
  190.     private class ConnectThread implements Runnable  
  191.     {  
  192.         @Override  
  193.         public void run()  
  194.         {  
  195.             while(!bConnected)  
  196.             {  
  197.                 try  
  198.                 {  
  199.                     socket = new Socket("127.0.0.1"9999);  
  200.                     bConnected = true;  
  201.                     dos = new DataOutputStream(socket.getOutputStream());  
  202.                     dis = new DataInputStream(socket.getInputStream());  
  203.                 } catch (Exception e)  
  204.                 {  
  205.                 }  
  206.             }  
  207.         }  
  208.           
  209.     }  
  210. }  



服务端 ChatServer.java:

  1. package com.chat.server;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.DataOutputStream;  
  5. import java.io.IOException;  
  6. import java.net.BindException;  
  7. import java.net.ServerSocket;  
  8. import java.net.Socket;  
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11.   
  12. /** 
  13.  * 聊天程序服务端 
  14.  * @author Tandaly 
  15.  * @date 2013-6-17 上午9:13:47 
  16.  */  
  17. public class ChatServer  
  18. {  
  19.   
  20.     private ServerSocket serverSocket = null;//服务socket对象  
  21.     private List<ClientThread> clients = new ArrayList<ClientThread>();//客户端集合  
  22.       
  23.     /** 
  24.      * 启动 
  25.      */  
  26.     public void start()  
  27.     {  
  28.         try  
  29.         {  
  30.             this.serverSocket = new ServerSocket(9999);  
  31.             System.out.println("----聊天服务器启动成功!----");  
  32.         } catch (BindException e)  
  33.         {  
  34.             System.out.println("SYSTEM ERROR:聊天服务启动失败,端口被占用");  
  35.             System.exit(0);  
  36.         } catch (IOException e1)  
  37.         {  
  38.             System.out.println("SYSTEM ERROR:发生异常");  
  39.             System.exit(0);  
  40.         }  
  41.           
  42.         try  
  43.         {  
  44.             while(true)  
  45.             {  
  46.                 Socket socket = this.serverSocket.accept();  
  47.                 ClientThread clientThread = new ClientThread(socket);//创建客户端消息线程  
  48.                 new Thread(clientThread).start();//启动处理客户端消息线程  
  49.                 this.clients.add(clientThread);//把当前读取到客户端加入到客户端集合中  
  50.             }  
  51.         } catch (IOException e)  
  52.         {  
  53.             e.printStackTrace();  
  54.         }  
  55.     }  
  56.       
  57.     /** 
  58.      * 入口函数 
  59.      * @param args 
  60.      */  
  61.     public static void main(String[] args)  
  62.     {  
  63.         new ChatServer().start();  
  64.     }  
  65.       
  66.     /** 
  67.      * 处理客户端消息线程类 
  68.      * @author Tandaly 
  69.      * @date 2013-6-17 上午9:37:59 
  70.      */  
  71.     private class ClientThread implements Runnable  
  72.     {  
  73.         private Socket socket;  
  74.         private DataInputStream dis;  
  75.         private DataOutputStream dos;  
  76.           
  77.         public ClientThread(Socket socket)  
  78.         {  
  79.             this.socket = socket;  
  80.               
  81.             try  
  82.             {  
  83.                 this.dis = new DataInputStream(this.socket.getInputStream());  
  84.                 this.dos = new DataOutputStream(this.socket.getOutputStream());  
  85.             } catch (IOException e)  
  86.             {  
  87.                 e.printStackTrace();  
  88.             }  
  89.         }  
  90.           
  91.         /** 
  92.          * 发送消息给客户端 
  93.          * @param txt 
  94.          */  
  95.         public void send(String txt)  
  96.         {  
  97.             try  
  98.             {  
  99.                 this.dos.writeUTF(txt);  
  100.             } catch (IOException e)  
  101.             {  
  102.                 System.out.println("SYSTEM:发送消息失败,客户端可能已经下线!");  
  103.             }//发送消息到客户端  
  104.         }  
  105.           
  106.         @Override  
  107.         public void run()  
  108.         {  
  109.             try  
  110.             {  
  111.                 while(true)  
  112.                 {  
  113.                     String txt = this.dis.readUTF();//读取客户端消息  
  114.                     System.out.println("消息:" + txt);  
  115.                       
  116.                     //向客户端群发消息  
  117.                     for(ClientThread client:clients)  
  118.                     {  
  119.                         if(this != client)  
  120.                         {  
  121.                             client.send(txt);  
  122.                         }  
  123.                     }  
  124.                 }  
  125.             } catch (IOException e)  
  126.             {  
  127.                 clients.remove(this);//移除当前客户端  
  128.                 try {  
  129.                     Thread.sleep(1000);  
  130.                 } catch (InterruptedException ex) {  
  131.                     ex.printStackTrace();  
  132.                 }  
  133.                 Thread.currentThread().interrupt();//终止当前线程  
  134.                 System.out.println("SYSTEM:线程" + Thread.currentThread().getName() + "被销毁");  
  135.             }  
  136.         }  
  137.           
  138.     }  
  139. }  



作者:Tandaly

出处:http://blog.csdn.net/tandaly/article/details/9110995


Viewing all articles
Browse latest Browse all 583

Trending Articles