zoukankan      html  css  js  c++  java
  • java Socket多线程聊天程序

    参考JAVA 通过 Socket 实现 TCP 编程

    参考java Socket多线程聊天程序(适合初学者)

    以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。

    一个非常简单的java聊天程序,有客户端和服务器端,目前只有群聊功能,其他的所有功能都可以在这个基础上添加,现在我分享出来主要是为了保持一个最简单的java聊天程序便于初学者学习,界面也非常的简洁,只有两个文件,主要是用了socket,java多线程,知识点不是很多,很适合初学者

    服务器端程序:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.SocketException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * @Auther: 李景然
     * @Date: 2018/5/17 10:12
     * @Description:
     */
    public class TKServer extends JFrame implements ActionListener {
    
        private Map<Integer, Socket> clients = new HashMap<Integer, Socket>();
        private JTextArea msg = new JTextArea("服务器消息接收器
    
    ");
        private JTextArea input = new JTextArea();
        private JButton msgSend = new JButton("发送群消息");
    
        public TKServer() {
            // TODO Auto-generated constructor stub
            this.setVisible(true);
            this.setTitle("服务器");
            this.setSize(550, 750);
            this.setResizable(true);
            this.setLayout(new FlowLayout());
            this.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent arg0) {
                    // TODO Auto-generated method stub
                    super.windowClosing(arg0);
                    System.exit(0);
                }
            });
            input.setColumns(40);
            input.setRows(5);
            input.setAutoscrolls(true);
            msgSend.addActionListener(this);
            msgSend.setActionCommand("sendMsg");
            msg.setAutoscrolls(true);
            msg.setColumns(40);
            msg.setRows(30);
    
            JScrollPane spanel = new JScrollPane(msg);
            JScrollPane editpanel = new JScrollPane(input);
            this.add(spanel);
            this.add(editpanel);
            this.add(msgSend);
        }
    
        public static void main(String[] args) {
    
            new TKServer().listenClient();
        }
    
        public void listenClient() {
    
            String temp = "";
            try {
                //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
                // 定义一个ServerSocket监听在端口8899上
                ServerSocket server = new ServerSocket(8899);
                while (true) {
                    System.out.println("服务器端正在监听");
                    Socket socket = server.accept();
                    clients.put(socket.getPort(), socket);
                    temp = "客户端" + socket.getPort() + " 连接";
                    this.apppendMsg(temp);
                    new mythread(socket, this).start();
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    
        public void apppendMsg(String msg) {
    
            this.msg.append(msg + "
    ");
        }
    
        public void sendMsgToAll(Socket fromSocket, String msg) {
    
            Set<Integer> keset = this.clients.keySet();
            java.util.Iterator<Integer> iter = keset.iterator();
            while (iter.hasNext()) {
                int key = iter.next();
                Socket socket = clients.get(key);
                if (socket != fromSocket) {
                    try {
                        if (socket.isClosed() == false) {
                            if (socket.isOutputShutdown() == false) {
    
                                Writer writer = new OutputStreamWriter(
                                        socket.getOutputStream());
                                writer.write(msg);
                                writer.flush();
                            }
                        }
                    } catch (SocketException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            }
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
    
            String temp = "";
            if ("sendMsg".equals(e.getActionCommand())) {
                if ((temp = this.input.getText()) != null) {
                    System.out.println("开始向客户端群发消息");
                    this.apppendMsg("服务器-->" + temp);
                    Set<Integer> keset = this.clients.keySet();
                    java.util.Iterator<Integer> iter = keset.iterator();
                    while (iter.hasNext()) {
                        int key = iter.next();
                        Socket socket = clients.get(key);
                        try {
                            Writer writer = new OutputStreamWriter(socket.getOutputStream());
                            writer.write(temp);
                            writer.flush();
                        } catch (SocketException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }
                    this.input.setText("");
                }
            }
        }
    }
    
    class mythread extends Thread {
    
        private Socket socket = null;
        private TKServer server = null;
        private InputStreamReader reader = null;
        char chars[] = new char[64];
        int len;
        private String temp = null;
    
        public mythread(Socket socket, TKServer server) {
            // TODO Auto-generated constructor stub
    
            this.socket = socket;
            this.server = server;
            init();
        }
    
        private void init() {
    
            try {
                reader = new InputStreamReader(socket.getInputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            
            System.out.println("子线程开始工作");
            while (true) {
                try {
                    System.out.println("服务器 线程" + this.getId() + "-->开始从客户端读取数据——>");
                    while ((len = ((Reader) reader).read(chars)) != -1) {
                        temp = new String(chars, 0, len);
                        System.out.println("客户端" + socket.getPort() + "说-->" + temp);
                        server.apppendMsg("客户端" + socket.getPort() + "说-->" + temp);
                        server.sendMsgToAll(this.socket, "客户端" + socket.getPort() + "说-->" + temp);
                    }
                    if (socket.getKeepAlive() == false) {
                        ((Reader) reader).close();
                        temp = "客户端" + socket.getPort() + "-->退出";
                        server.apppendMsg(temp);
                        socket.close();
                        this.stop();
                    }
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                    try {
                        ((Reader) reader).close();
                        socket.close();
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            }
        }
    }

    客户端程序:

    /**
     * @Auther: 李景然
     * @Date: 2018/5/17 10:15
     * @Description:
     */
    
    import java.awt.FlowLayout;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.Reader;
    import java.io.Writer;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import javax.swing.*;
    
    public class TKClient extends JFrame implements ActionListener {
    
        // 为了简单起见,所有的异常都直接往外抛
        String host = "127.0.0.1"; // 要连接的服务端IP地址
        int port = 8899; // 要连接的服务端对应的监听端口
        mythread thread = null;
        Socket client = null;
        Writer writer = null;
    
        private JTextArea msg = new JTextArea("客户端消息接收器
    
    ");
        private JTextArea input = new JTextArea();
        private JButton msgSend = new JButton("发送群消息");
    
        public TKClient() {
            // TODO Auto-generated constructor stub
    
            initSocket();
            this.setVisible(true);
            this.setTitle("客户端");
            this.setSize(550, 750);
            this.setResizable(true);
            this.setLayout(new FlowLayout());
            this.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent arg0) {
                    // TODO Auto-generated method stub
                    super.windowClosing(arg0);
                    try {
                        if (client != null) {
                            client.close();
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    if (thread != null) {
                        thread.stop();
                    }
                    System.exit(0);
                }
            });
            input.setColumns(40);
            input.setRows(10);
            input.setAutoscrolls(true);
            msgSend.addActionListener(this);
            msgSend.setActionCommand("sendMsg");
            msg.setAutoscrolls(true);
            msg.setColumns(40);
            msg.setRows(25);
            JScrollPane spanel = new JScrollPane(msg);
            JScrollPane editpanel = new JScrollPane(input);
            this.add(spanel);
            this.add(editpanel);
            this.add(msgSend);
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
    
            new TKClient();
        }
    
        public void initSocket() {
    
            try {
                client = new Socket(this.host, this.port);
                writer = new OutputStreamWriter(client.getOutputStream());
                // 建立连接后就可以往服务端写数据了
                thread = new mythread(client, this);
                thread.start();
                this.appendMsg("已连上服务器");
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                this.appendMsg("不能连接上服务器");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                this.appendMsg("不能连接上服务器");
            }
        }
    
        public void appendMsg(String msg) {
    
            this.msg.append(msg + "
    ");
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
    
            String temp = "";
            try {
                if ("sendMsg".equals(e.getActionCommand())) {
                    if ((temp = this.input.getText()) != null) {
                        writer.write(temp);
                        writer.flush();
                        this.appendMsg("我(" + this.client.getLocalPort() + ")说——>" + temp);
                        this.input.setText("");
                    }
                }
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
    
    class mythread extends Thread {
    
        private Socket socket = null;
        private Reader reader = null;
        private int len = 0;
        char chars[] = new char[64];
        private TKClient client = null;
        private String temp = "";
    
        public mythread(Socket socket, TKClient client) {
            // TODO Auto-generated constructor stub
    
            this.socket = socket;
            this.client = client;
            try {
                reader = new InputStreamReader(socket.getInputStream());
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
    
            super.run();
            System.out.println("客户端 子线程" + this.getId() + "-->开始工作");
            while (true) {
                try {
                    if (socket.isClosed() == false) {
                        if (socket.isInputShutdown() == false) {
                            while ((len = ((Reader) reader).read(chars)) != -1) {
                                temp = "服务器说——>" + new String(chars, 0, len);
                                client.appendMsg(temp);
                                System.out.println();
                            }
                        }
                    } else {
                        if (socket.getKeepAlive() == false) {
                            reader.close();
                            socket.close();
                            this.stop();
                        }
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 蓝桥杯 算法提高 小X的购物计划
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java实现 第十一届 蓝桥杯 (高职专科组)省内模拟赛
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    Java 第十一届 蓝桥杯 省模拟赛 小明的城堡
    129. Sum Root to Leaf Numbers
    117. Populating Next Right Pointers in Each Node II
  • 原文地址:https://www.cnblogs.com/lijingran/p/9050395.html
Copyright © 2011-2022 走看看