//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(); } }