java之Socket实现简易的聊天室程序

客户端程序:

  1 package 聊天室;
  2 
  3 import java.awt.BorderLayout;
  4 import java.awt.TextArea;
  5 import java.awt.TextField;
  6 import java.awt.event.ActionEvent;
  7 import java.awt.event.ActionListener;
  8 import java.awt.event.WindowAdapter;
  9 import java.awt.event.WindowEvent;
 10 import java.io.DataInputStream;
 11 import java.io.DataOutputStream;
 12 import java.io.IOException;
 13 import java.net.Socket;
 14 import java.net.SocketException;
 15 import java.net.UnknownHostException;
 16 
 17 import javax.swing.JFrame;
 18 
 19 public class ChatClient extends JFrame{
 20     TextField tfText=new TextField();//发送文本框
 21     TextArea taContent=new TextArea();//聊天记录框
 22     Socket s=null;
 23     DataOutputStream dos=null;
 24     DataInputStream dis=null;
 25     private boolean bConnected=false;
 26     
 27     public static void main(String[] args) {
 28         new ChatClient().init();
 29 
 30     }
 31     
 32     //窗体显示
 33     public void init() {
 34 
 35         setBounds(400,300,300,300);
 36         add(tfText,BorderLayout.SOUTH);
 37         add(taContent,BorderLayout.NORTH);
 38         pack();//调整此窗口的大小,以适合其子组件的首选大小和布局
 39         addWindowListener(new WindowAdapter() {
 40 
 41             @Override
 42             public void windowClosing(WindowEvent e) {
 43                 disconnect();
 44                 System.exit(0);
 45             }
 46             
 47         });
 48         tfText.addActionListener(new TFListener());
 49         connect();
 50         new Thread(new RecvThread()).start();
 51         setVisible(true);
 52     }
 53     
 54     //连接服务器
 55     private void connect() {
 56         try {
 57             s=new Socket("192.168.56.1",10086);
 58             dos=new DataOutputStream(s.getOutputStream());
 59             dis=new DataInputStream(s.getInputStream());
 60 System.out.println("connected!");
 61             bConnected=true;
 62         } catch (UnknownHostException e) {
 63             e.printStackTrace();
 64         } catch (IOException e) {
 65             e.printStackTrace();
 66         }
 67     }
 68     
 69     //资源释放
 70     private void disconnect() {
 71         try {
 72             dos.close();
 73             s.close();
 74         } catch (IOException e) {
 75             e.printStackTrace();
 76         }
 77     }
 78     
 79     //TextField的事件处理
 80     private class TFListener implements ActionListener{
 81 
 82         @Override
 83         public void actionPerformed(ActionEvent e) {
 84             String str=tfText.getText().trim();
 85             tfText.setText("");
 86             try {
 87                 dos.writeUTF(str);
 88                 dos.flush();
 89                 
 90             } catch (IOException e1) {
 91                 e1.printStackTrace();
 92             }
 93             
 94         }
 95         
 96     }
 97     
 98         //客户端接收其他客户端发送的信息
 99     private class RecvThread implements Runnable{
100 
101         @Override
102         public void run() {
103             try {
104                 while(bConnected) {
105                     String str=dis.readUTF();
106                     //System.out.println(str);
107                     taContent.setText(taContent.getText()+str+'\n');
108                 }
109                 
110             }catch(SocketException e) {
111                 System.out.println("客户端被关闭了!");
112             }catch(IOException e){
113                 e.printStackTrace();
114             }
115             
116         }
117         
118     }
119 }
120     
View Code

服务器程序:

  1 package 聊天室;
  2 
  3 import java.io.DataInputStream;
  4 import java.io.DataOutputStream;
  5 import java.io.EOFException;
  6 import java.io.IOException;
  7 import java.net.BindException;
  8 import java.net.ServerSocket;
  9 import java.net.Socket;
 10 import java.net.SocketException;
 11 import java.util.ArrayList;
 12 import java.util.List;
 13 
 14 
 15 public class ChatServer {
 16     ServerSocket ss=null;
 17     private boolean started=false;//判断是否绑定服务器
 18     private boolean bConnected=false;//判断是否连接客户端
 19     List<Client> clientList=new ArrayList<>();
 20     
 21     public static void main(String[] args) {
 22         new ChatServer().start();
 23 
 24     }
 25     
 26     private void start() {
 27         try {
 28             //创建服务器端接收数据对象
 29             ss=new ServerSocket(10086);
 30             started=true;
 31         }catch(BindException e) {
 32             System.out.println("端口使用中....请关掉相关程序并重新运行服务器");
 33             System.exit(0);
 34         }catch(IOException e) {
 35             e.printStackTrace();
 36         }
 37             
 38         try {
 39             while(started) {//已经绑定到服务器,不断接受客户端的连接            
 40                 Socket s=ss.accept();
 41                 System.out.println("a client connected!");
 42                 Client c=new Client(s);
 43                 new Thread(c).start();        
 44                 clientList.add(c);
 45             }    
 46         }catch(IOException e) {
 47             e.printStackTrace();            
 48         }finally {
 49             try {
 50                 ss.close();
 51             } catch (IOException e) {
 52                 e.printStackTrace();
 53             }
 54         }                
 55     }
 56     
 57     //每一个线程负责一个客户端
 58     class Client implements Runnable{
 59         private Socket s=null;
 60         private DataInputStream dis=null;
 61         private DataOutputStream dos=null;
 62 
 63         public Client(Socket s) {
 64             this.s=s;
 65             try {
 66                 dis=new DataInputStream(s.getInputStream());
 67                 dos=new DataOutputStream(s.getOutputStream());
 68                 bConnected=true;
 69             } catch (IOException e) {
 70                 e.printStackTrace();
 71             }
 72         }
 73         @Override
 74         public void run() {
 75             try {
 76                 while(bConnected) {//已经连上了客户端,开始读取客户端的数据到控制台
 77                     String str=dis.readUTF();
 78                     System.out.println(str);
 79                     //将其中一个客户端发送的数据发送至其他客户端
 80                     for(int i=0;i<clientList.size();i++) {
 81                         Client c=clientList.get(i);
 82                         c.send(str);
 83                     }
 84                 }
 85             }catch(EOFException e) {
 86                 System.out.println("Client close");        
 87             }catch(SocketException e) {
 88                 System.out.println("a client quit!");
 89             }catch(IOException e) {
 90                 e.printStackTrace();                    
 91             }finally {
 92                 try {
 93                     if(s!=null) s.close();
 94                     if(dis!=null) dis.close();
 95                     if(dos!=null) dos.close();
 96                 } catch (IOException e1) {
 97                     e1.printStackTrace();
 98                 }
 99             }
100             
101         }
102         
103         //发送消息给其他客户端
104         public void send(String str) {
105             try {
106                 dos.writeUTF(str);//将其中一个客户端发送的数据写到服务器里
107             } catch (IOException e) {
108                 clientList.remove(this);
109                 System.out.println("对方退出了。我从list里面去除了!");
110                 //e.printStackTrace();
111             }
112         }
113         
114     }
115     
116     
117 
118 }
View Code

注意事项:要先启动服务器,再启动客户端

结果:

 

posted @ 2020-06-16 16:05  PLG  阅读(561)  评论(0编辑  收藏  举报