综合简单聊天系统

来源:互联网 发布:大数据平台调度系统 编辑:程序博客网 时间:2024/05/22 17:40

综合简单聊天系统

在上一篇博客中,我们写了一个简单的群聊系统,但是我们要想单独只对某一个客户端聊天,却不能实现。下面,我们综合之前写的,写一个综合的既能群聊,又能单聊的简单聊天系统。

代码示例

创建客户端Client

import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.Socket;import java.net.UnknownHostException;import java.util.Calendar;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import net.sf.json.JSONObject;public class Client extends JFrame implements ActionListener {    Socket s;    PrintWriter pw;    BufferedReader br;    JTextArea jta;    JTextField jtf;    JButton jb;    JPanel jp;    JScrollPane jsp;    JOptionPane jop;    String username;    public static void main(String[] args) {        new Client();    }    public Client() {        jta = new JTextArea();        jsp = new JScrollPane(jta);        jtf = new JTextField(15);        jb = new JButton("发送");        jb.addActionListener(this);        jp = new JPanel();        jp.add(jtf);        jp.add(jb);        this.add(jsp, BorderLayout.CENTER);        this.add(jp, BorderLayout.SOUTH);        this.setSize(300, 200);        username = JOptionPane.showInputDialog("请输入用户名");        this.setTitle("客户端" + username);        this.setVisible(true);        try {            s = new Socket("127.0.0.1", 10000);            JOptionPane.showMessageDialog(this, "连接成功");            write(username);            Thread t = new Thread(new GetServerToClientMessage(Client.this));            t.start();        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void actionPerformed(ActionEvent e) {        String str = creatMessage();        write(str);        jtf.setText("");    }    /**     *      * @return 返回一个发送给单人的信息     */    public String creatMessage() {        JSONObject obj = new JSONObject();        String msg = jtf.getText();        jta.append(username + "说:" + msg + "\n");        obj.put("message", msg);        obj.put("type", "toSingle");        obj.put("from", username);        obj.put("to", "2");        Calendar cal = Calendar.getInstance();        long time = cal.getTimeInMillis();        obj.put("time", "" + time);        return obj.toString();    }    /**     * 将此消息发送给服务器     *      * @param msg 发送的消息     *            */    public void write(String msg) {        try {            pw = new PrintWriter(s.getOutputStream());            pw.println(msg);            pw.flush();        } catch (IOException e) {            e.printStackTrace();        }    }    public void read() {        try {            while (true) {                br = new BufferedReader(new InputStreamReader(s.getInputStream()));                jta.append(br.readLine() + "\n");            }        } catch (IOException e) {            e.printStackTrace();        }    }    public String getUsername(){        return username;    }}

创建客户端接收服务器消息的线程类

public class GetServerToClientMessage implements Runnable {    private Client client;    public GetServerToClientMessage(Client client) {        this.client = client;    }    @Override    public void run() {        client.read();    }}

创建服务器端Server

import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Set;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;import net.sf.json.JSONObject;public class Server extends JFrame implements ActionListener {    PrintWriter pw;    BufferedReader br;    JTextArea jta;    JTextField jtf;    JButton jb;    JPanel jp;    JScrollPane jsp;    HashMap<String, Socket> sockets;    ServerSocket ss;    public static void main(String[] args) {        new Server();    }    public Server() {        jta = new JTextArea();        jsp = new JScrollPane(jta);        jtf = new JTextField(15);        jb = new JButton("发送");        jb.addActionListener(this);        jp = new JPanel();        jp.add(jtf);        jp.add(jb);        this.add(jsp, BorderLayout.CENTER);        this.add(jp, BorderLayout.SOUTH);        this.setSize(300, 200);        this.setTitle("服务器");        this.setVisible(true);        new Thread(new Runnable() {            @Override            public void run() {                try {                    ss = new ServerSocket(10000);                    sockets = new HashMap<>();                    while (true) {                        Socket socket = ss.accept();                        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));                        String username = br.readLine();                        jta.append("客户端" + username + "已成功连接服务器\n");                        sockets.put(username, socket);                        Thread t = new Thread(new GetClientToServerMessage(Server.this, socket));                        t.start();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    }    @Override    public void actionPerformed(ActionEvent e) {// 发送        try {            Set<String> set = sockets.keySet();            Iterator<String> it = set.iterator();            while (it.hasNext()) {                Socket socket = sockets.get(it.next());                pw = new PrintWriter(socket.getOutputStream(), true);                String str = jtf.getText();                jta.append("服务器说:" + str + "\n");                pw.println("服务器公告:"+str);                pw.flush();            }            jtf.setText("");        } catch (IOException e1) {            e1.printStackTrace();        }    }    public void readMsg(String msg) {        JSONObject obj = JSONObject.fromObject(msg);        String type = obj.getString("type");        if (type.equals("toSingle")) {            String message = obj.getString("message");            String to = obj.getString("to");            String from = obj.getString("from");            String time = obj.getString("time");            Socket toSocket = sockets.get(to);            try {                PrintWriter pw = new PrintWriter(toSocket.getOutputStream());                pw.println(from + "说:" + message);                pw.flush();            } catch (IOException e) {                e.printStackTrace();            }        } else if (type.equals("toAll")) {            String message = obj.getString("message");            String from = obj.getString("from");            try {                Set<String> set = sockets.keySet();                Iterator<String> it = set.iterator();                while (it.hasNext()) {                    String otherName = it.next().toString();                    if (!otherName.equals(from)) {                        Socket socket = sockets.get(otherName);                        pw = new PrintWriter(socket.getOutputStream(), true);                        pw.println(from + "说:" + message);                        pw.flush();                    }                }            } catch (IOException e1) {                e1.printStackTrace();            }        }        jta.append(msg + "\n");    }}

创建服务器接收客户端消息的线程类

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;public class GetClientToServerMessage implements Runnable {    private Server server;    private Socket socket;    public GetClientToServerMessage(Server server, Socket socket) {        this.server = server;        this.socket = socket;    }    @Override    public void run() {        try {                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));                while (true) {                String msg = br.readLine();                server.readMsg(msg);            }        } catch (IOException e) {            e.printStackTrace();        }    }}

运行结果:

下面我们进行测试,登录客户端,用户名为1,将createMessage()方法中“type”改为“toAll”,让1实现群发。登录客户端,用户名为2,将createMessage()方法中“type”的值改为“toSingle”,“to”得值改为“3”,让2单独给3聊天。登录客户端,用户名为3,将createMessage()方法中“type”的值改为“toSingle”,“to”得值改为“2”,让3单独给2聊天。我们也可以将此实现做到客户端界面上去,这样就不用修改代码了!这里我就不做了!给大家做一个测试!
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

0 0