java小程序简单的多人聊天

//Clien端代码
package gf;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Client1 implements ActionListener{
        Socket s;
        String name;
        PrintWriter pw;
        //1.添加组件
        JFrame f; //窗口
        JTextArea jta;//显示聊天的文本域
        JLabel lab;//显示名字
        JTextField jtf;//输入信息的框
        JButton btn;//发送按钮
            
       public Client1() {
             //2.初始化组件
             f=new JFrame();
             jta=new JTextArea(20,20);    
             jta.setFont(new Font("楷体",Font.BOLD,24));
             jta.setEditable(false);
             jtf=new JTextField(30);
             btn=new JButton("发送");
        try {
            s = new Socket("192.168.43.54", 8088);// 其实就是服务器建立连接
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        //3.输入框输入昵称
        name=JOptionPane.showInputDialog("请输入昵称:");
         lab=new JLabel(name+":");
         
        RDMesasage r=new RDMesasage();//在构造方法中,启动线程
        Thread t=new Thread(r);
        t.start();
        
        init();
        show();
        btn.addActionListener(this);
        jtf.addActionListener(this);    
    }
       

    //4.自定义方法 添加各组组件。
      public void init() {
          
        //创建可滚动的画布,并将显示信息的文本域添加上去 
        JScrollPane jp=new JScrollPane(jta);
        
        //创建普通画布 JPanel 是流式布局添加。       
        JPanel p=new JPanel();
        p.add(lab);
        p.add(jtf);
        p.add(btn);
        
        //把画布添加到窗口JFrame上
        f.add(jp,BorderLayout.CENTER);
        f.add(p, BorderLayout.SOUTH);
    }     
      
      //5.设置窗口
     public void show(){
         f.pack();//自适应大小
         f.setDefaultCloseOperation(3);
         f.setVisible(true);
         f.setLocationRelativeTo(null);
         f.setTitle("聊天窗口");
     }
      
       
    public void start() {
        //从Socket获取输出流,向服务器发送信息
        try {
            OutputStream os=s.getOutputStream();//发送信息用OutputStream
            OutputStreamWriter osw=new OutputStreamWriter(os);//一个字一个字的写入
             pw=new PrintWriter(osw,true);    //一行一行的写入
            pw.println(name);    
                
//            Scanner s=new Scanner(System.in);        
//            System.out.println("请输入昵称:");
//            String name=s.nextLine();                
//            while(true){
//            System.out.println("请输入向服务器发出的信息:");
//            pw.println(s.nextLine());
//            }
                
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
    
    
    class RDMesasage implements Runnable{// 创建线程,读取服务器端发来的信息

        @Override
        public void run() {
            // TODO 自动生成的方法存根
            try {
                InputStream is = s.getInputStream();//从自己对应的socket中获取到输入流,读取自己发送的信息
                InputStreamReader isr=new InputStreamReader(is);//一个字一个字的读取
                BufferedReader br=new BufferedReader(isr);//一行一行的读取
                String str=null;
                while((str=br.readLine())!=null){
//                    System.out.println("服务器返回的信息:"+str);
                    jta.append(str);
                    jta.append("\n");
                }
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }    
        }    
    }

    public static void main(String[] args) {
        Client1 c = new Client1();
        c.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO 自动生成的方法存根
        pw.println(jtf.getText());
        jtf.setText(" ");
        
    }
}


//service代码
package gf;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Server {
    // 创建集合,存放所有***端的pw(out流)
    //数据类型<>
    List<PrintWriter> pws=new ArrayList<PrintWriter>();
    ServerSocket sc;
    public Server() {
        try {
            sc = new ServerSocket(8088);// 给服务器申请端口
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();}
    }

    public void start() {
        try {
            int count = 0;
            System.out.println("等待***连接........");
            while (true) {
                Socket s= sc.accept();//s 接收 accept接收的的Socket;
                count++;
                System.out.println("第" + count + "个***连接成功!!!!!!!!!");
                
                HandleClient hc=new HandleClient(s);//每接收一个socket,就创建一个线程。
                hc.start();
                
            }            
         } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
    
    //创建线程模板,每连接到一个***端,就根据这个模板创建一个线程实例,来负责这个***端的通信
    //内部类,供外部类server使用.
    class HandleClient extends Thread{
        Socket s;
        PrintWriter pw;
        String name;
          public HandleClient(Socket s){
              this.s=s;   }
          
          public void run(){
              try {
                    //从与该***端对应的socket中获取到输入流,读取该***端发送的信息
                    InputStream is=s.getInputStream();
                    //一个字一个字的读取
                    InputStreamReader isr=new InputStreamReader(is);
                    //一行一行的读取
                    BufferedReader br=new BufferedReader(isr);    
                    //获取该***端的输出流,向该***端返回信息
                    OutputStream os=s.getOutputStream();
                    OutputStreamWriter osw=new OutputStreamWriter(os);
                    pw=new PrintWriter(osw,true);
                    
                    name=br.readLine();
                    for(PrintWriter p:pws){
                    p.println(name+"上线了!当前在线人数:"+(pws.size()+1)+"人!");
                    }
                    //把客对应的pw添加到集合中。
                    pws.add(pw);
                    String str=null;
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    while((str=br.readLine())!=null){
                    Date d=new Date();
                    String time=sdf.format(d);
                    //在服务器的控制台上显示信息    
                    System.out.println(name+":"+str);
                    // 遍历集合访问到每一个pw用每一个pw向***端发送信息
                    for (int i = 0; i < pws.size(); i++) { 
                        pws.get(i).println(name + ":" + str+"\n"+time);
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
                System.out.println("系统出错.....");
            }finally{
                pws.remove(pw);
                for(PrintWriter p:pws){
                p.println(name+"下线了!当前在线人数:"+(pws.size())+"人!");
                    }
                pw.close();
            }  
        }
    }
    
    public static void main(String[] args) {
        Server s = new Server();
        s.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值