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();
                }
            }
        }
    }
  • 相关阅读:
    git——学习笔记(一)
    技术大牛的博客//文档
    python——周边
    数据挖掘算法:关联分析二(Apriori)
    数据挖掘算法:关联分析一(基本概念)
    Python入门5(pandas中merge中的参数how)
    Spark入门3(累加器和广播变量)
    Spark入门2(Spark简析)
    Spark入门1(以WordCount为例讲解flatmap和map之间的区别)
    算法入门1(决策树)
  • 原文地址:https://www.cnblogs.com/lijingran/p/9050395.html
Copyright © 2011-2022 走看看