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
服务器程序:
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 }
注意事项:要先启动服务器,再启动客户端
结果: