• 热门专题

Java Socket实现多人聊天室-swing做UI

作者:黄宇强的博客  发布日期:2011-08-31 16:03:06
Tag标签:Java  Socket  实现  多人聊天室  
  • 今天翻硬盘的workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。但写得还不错,
     
    至少算个有模有样的聊天室工具。我简单的修改了一下,拿出来跟大家分享一下,仅供参考。。。
     
             界面是用swing写的,还不懒,简约大方。有图有真相:

    正如上图所示,这个程序分为 服务器端和客户端,说白了就是 两个main class,用eclipse直接运行之。。。。。
     
               聊天室的设计思想是 :在局域网下, 利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连
    接的时候,服务器端通过IO流反馈“上线用户”信息给客户端,客户端也使用线程不停的接收服务器的信息,从而实现多人在线聊天功能。
     
    程序中有三个类,分别 Server.java(服务器端)、Client(客户端)、User.java(javabean)。代码如下:
     
    Server.java(服务器端):

    import java.awt.BorderLayout;  
    import java.awt.Color;  
    import java.awt.GridLayout;  
    import java.awt.Toolkit;  
    import java.awt.event.ActionEvent;  
    import java.awt.event.ActionListener;  
    import java.awt.event.WindowAdapter;  
    import java.awt.event.WindowEvent;  
    import java.io.BufferedReader;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.io.PrintWriter;  
    import java.net.BindException;  
    import java.net.ServerSocket;  
    import java.net.Socket;  
    import java.util.ArrayList;  
    import java.util.StringTokenizer;  
      
    import javax.swing.DefaultListModel;  
    import javax.swing.JButton;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
    import javax.swing.JList;  
    import javax.swing.JOptionPane;  
    import javax.swing.JPanel;  
    import javax.swing.JScrollPane;  
    import javax.swing.JSplitPane;  
    import javax.swing.JTextArea;  
    import javax.swing.JTextField;  
    import javax.swing.border.TitledBorder;  
      
    public class Server {  
      
        private JFrame frame;  
        private JTextArea contentArea;  
        private JTextField txt_message;  
        private JTextField txt_max;  
        private JTextField txt_port;  
        private JButton btn_start;  
        private JButton btn_stop;  
        private JButton btn_send;  
        private JPanel northPanel;  
        private JPanel southPanel;  
        private JScrollPane rightPanel;  
        private JScrollPane leftPanel;  
        private JSplitPane centerSplit;  
        private JList userList;  
        private DefaultListModel listModel;  
      
        private ServerSocket serverSocket;  
        private ServerThread serverThread;  
        private ArrayList<ClientThread> clients;  
      
        private boolean isStart = false;  
      
        // 主方法,程序执行入口  
        public static void main(String[] args) {  
            new Server();  
        }  
      
        // 执行消息发送  
        public void send() {  
            if (!isStart) {  
                JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",  
                        JOptionPane.ERROR_MESSAGE);  
                return;  
            }  
            if (clients.size() == 0) {  
                JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",  
                        JOptionPane.ERROR_MESSAGE);  
                return;  
            }  
            String message = txt_message.getText().trim();  
            if (message == null || message.equals("")) {  
                JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",  
                        JOptionPane.ERROR_MESSAGE);  
                return;  
            }  
            sendServerMessage(message);// 群发服务器消息  
            contentArea.append("服务器说:" + txt_message.getText() + "\r\n");  
            txt_message.setText(null);  
        }  
      
        // 构造放法  
        public Server() {  
            frame = new JFrame("服务器");  
            // 更改JFrame的图标:  
            //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));  
            frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png")));  
            contentArea = new JTextArea();  
            contentArea.setEditable(false);  
            contentArea.setForeground(Color.blue);  
            txt_message = new JTextField();  
            txt_max = new JTextField("30");  
            txt_port = new JTextField("6666");  
            btn_start = new JButton("启动");  
            btn_stop = new JButton("停止");  
            btn_send = new JButton("发送");  
            btn_stop.setEnabled(false);  
            listModel = new DefaultListModel();  
            userList = new JList(listModel);  
      
            southPanel = new JPanel(new BorderLayout());  
            southPanel.setBorder(new TitledBorder("写消息"));  
            southPanel.add(txt_message, "Center");  
            southPanel.add(btn_send, "East");  
            leftPanel = new JScrollPane(userList);  
            leftPanel.setBorder(new TitledBorder("在线用户"));  
      
            rightPanel = new JScrollPane(contentArea);  
            rightPanel.setBorder(new TitledBorder("消息显示区"));  
      
            centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel,  
                    rightPanel);  
            centerSplit.setDividerLocation(100);  
            northPanel = new JPanel();  
            northPanel.setLayout(new GridLayout(1, 6));  
            northPanel.add(new JLabel("人数上限"));  
            northPanel.add(txt_max);  
            northPanel.add(new JLabel("端口"));  
            northPanel.add(txt_port);  
            northPanel.add(btn_start);  
            northPanel.add(btn_stop);  
            northPanel.setBorder(new TitledBorder("配置信息"));  
      
            frame.setLayout(new BorderLayout());  
            frame.add(northPanel, "North");  
            frame.add(centerSplit, "Center");  
            frame.add(southPanel, "South");  
            frame.setSize(600, 400);  
            //frame.setSize(Toolkit.getDefaultToolkit().getScreenSize());//设置全屏  
            int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
            int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
            frame.setLocation((screen_width - frame.getWidth()) / 2,  
                    (screen_height - frame.getHeight()) / 2);  
            frame.setVisible(true);  
      
            // 关闭窗口时事件  
            frame.addWindowListener(new WindowAdapter() {  
                public void windowClosing(WindowEvent e) {  
                    if (isStart) {  
                        closeServer();// 关闭服务器  
                    }  
                    System.exit(0);// 退出程序  
                }  
            });  
      
            // 文本框按回车键时事件  
            txt_message.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    send();  
                }  
            });  
      
            // 单击发送按钮时事件  
            btn_send.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent arg0) {  
                    send();  
                }  
            });  
      
            // 单击启动服务器按钮时事件  
            btn_start.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    if (isStart) {  
                        JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                        return;  
                    }  
                    int max;  
                    int port;  
                    try {  
                        try {  
                            max = Integer.parseInt(txt_max.getText());  
                        } catch (Exception e1) {  
                            throw new Exception("人数上限为正整数!");  
                        }  
                        if (max <= 0) {  
                            throw new Exception("人数上限为正整数!");  
                        }  
                        try {  
                            port = Integer.parseInt(txt_port.getText());  
                        } catch (Exception e1) {  
                            throw new Exception("端口号为正整数!");  
                        }  
                        if (port <= 0) {  
                            throw new Exception("端口号 为正整数!");  
                        }  
                        serverStart(max, port);  
                        contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port  
                                + "\r\n");  
                        JOptionPane.showMessageDialog(frame, "服务器成功启动!");  
                        btn_start.setEnabled(false);  
                        txt_max.setEnabled(false);  
                        txt_port.setEnabled(false);  
                        btn_stop.setEnabled(true);  
                    } catch (Exception exc) {  
                        JOptionPane.showMessageDialog(frame, exc.getMessage(),  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                    }  
                }  
            });  
      
            // 单击停止服务器按钮时事件  
            btn_stop.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    if (!isStart) {  
                        JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",  
                                JOptionPane.ERROR_MESSAGE);  
                        return;  
                    }  
                    try {  
                        closeServer();  
                        btn_start.setEnabled(true);  
                        txt_max.setEnabled(true);  
                        txt_port.setEnabled(true);  
                        btn_stop.setEnabled(false);  
                        contentArea.append("服务器成功停止!\r\n");  
                        JOptionPane.showMessageDialog(frame, "服务器成功停止!");  
                    } catch (Exception exc) {  
                        JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",  
                                JOptionPane.ERROR_MESSAGE);  
                    }  
                }  
            });  
        }  
      
        // 启动服务器  
        public void serverStart(int max, int port) throws java.net.BindException {  
            try {  
                clients = new ArrayList<ClientThread>();  
                serverSocket = new ServerSocket(port);  
                serverThread = new ServerThread(serverSocket, max);  
                serverThread.start();  
                isStart = true;  
            } catch (BindException e) {  
                isStart = false;  
                throw new BindException("端口号已被占用,请换一个!");  
            } catch (Exception e1) {  
                e1.printStackTrace();  
                isStart = false;  
                throw new BindException("启动服务器异常!");  
            }  
        }  
      
        // 关闭服务器  
        @SuppressWarnings("deprecation")  
        public void closeServer() {  
            try {  
                if (serverThread != null)  
                    serverThread.stop();// 停止服务器线程  
      
                for (int i = clients.size() - 1; i >= 0; i--) {  
                    // 给所有在线用户发送关闭命令  
                    clients.get(i).getWriter().println("CLOSE");  
                    clients.get(i).getWriter().flush();  
                    // 释放资源  
                    clients.get(i).stop();// 停止此条为客户端服务的线程  
                    clients.get(i).reader.close();  
                    clients.get(i).writer.close();  
                    clients.get(i).socket.close();  
                    clients.remove(i);  
                }  
                if (serverSocket != null) {  
                    serverSocket.close();// 关闭服务器端连接  
                }  
                listModel.removeAllElements();// 清空用户列表  
                isStart = false;  
            } catch (IOException e) {  
                e.printStackTrace();  
                isStart = true;  
            }  
        }  
      
        // 群发服务器消息  
        public void sendServerMessage(String message) {  
            for (int i = clients.size() - 1; i >= 0; i--) {  
                clients.get(i).getWriter().println("服务器:" + message + "(多人发送)");  
                clients.get(i).getWriter().flush();  
            }  
        }  
      
        // 服务器线程  
        class ServerThread extends Thread {  
            private ServerSocket serverSocket;  
            private int max;// 人数上限  
      
            // 服务器线程的构造方法  
            public ServerThread(ServerSocket serverSocket, int max) {  
                this.serverSocket = serverSocket;  
                this.max = max;  
            }  
      
            public void run() {  
                while (true) {// 不停的等待客户端的链接  
                    try {  
                        Socket socket = serverSocket.accept();  
                        if (clients.size() == max) {// 如果已达人数上限  
                            BufferedReader r = new BufferedReader(  
                                    new InputStreamReader(socket.getInputStream()));  
                            PrintWriter w = new PrintWriter(socket  
                                    .getOutputStream());  
                            // 接收客户端的基本用户信息  
                            String inf = r.readLine();  
                            StringTokenizer st = new StringTokenizer(inf, "@");  
                            User user = new User(st.nextToken(), st.nextToken());  
                            // 反馈连接成功信息  
                            w.println("MAX@服务器:对不起," + user.getName()  
                                    + user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");  
                            w.flush();  
                            // 释放资源  
                            r.close();  
                            w.close();  
                            socket.close();  
                            continue;  
                        }  
                        ClientThread client = new ClientThread(socket);  
                        client.start();// 开启对此客户端服务的线程  
                        clients.add(client);  
                        listModel.addElement(client.getUser().getName());// 更新在线列表  
                        contentArea.append(client.getUser().getName()  
                                + client.getUser().getIp() + "上线!\r\n");  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }  
      
        // 为一个客户端服务的线程  
        class ClientThread extends Thread {  
            private Socket socket;  
            private BufferedReader reader;  
            private PrintWriter writer;  
            private User user;  
      
            public BufferedReader getReader() {  
                return reader;  
            }  
      
            public PrintWriter getWriter() {  
                return writer;  
            }  
      
            public User getUser() {  
                return user;  
            }  
      
            // 客户端线程的构造方法  
            public ClientThread(Socket socket) {  
                try {  
                    this.socket = socket;  
                    reader = new BufferedReader(new InputStreamReader(socket  
                            .getInputStream()));  
                    writer = new PrintWriter(socket.getOutputStream());  
                    // 接收客户端的基本用户信息  
                    String inf = reader.readLine();  
                    StringTokenizer st = new StringTokenizer(inf, "@");  
                    user = new User(st.nextToken(), st.nextToken());  
                    // 反馈连接成功信息  
                    writer.println(user.getName() + user.getIp() + "与服务器连接成功!");  
                    writer.flush();  
                    // 反馈当前在线用户信息  
                    if (clients.size() > 0) {  
                        String temp = "";  
                        for (int i = clients.size() - 1; i >= 0; i--) {  
                            temp += (clients.get(i).getUser().getName() + "/" + clients  
                                    .get(i).getUser().getIp())  
                                    + "@";  
                        }  
                        writer.println("USERLIST@" + clients.size() + "@" + temp);  
                        writer.flush();  
                    }  
                    // 向所有在线用户发送该用户上线命令  
                    for (int i = clients.size() - 1; i >= 0; i--) {  
                        clients.get(i).getWriter().println(  
                                "ADD@" + user.getName() + user.getIp());  
                        clients.get(i).getWriter().flush();  
                    }  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
      
            @SuppressWarnings("deprecation")  
            public void run() {// 不断接收客户端的消息,进行处理。  
                String message = null;  
                while (true) {  
                    try {  
                        message = reader.readLine();// 接收客户端消息  
                        if (message.equals("CLOSE"))// 下线命令  
                        {  
                            contentArea.append(this.getUser().getName()  
                                    + this.getUser().getIp() + "下线!\r\n");  
                            // 断开连接释放资源  
                            reader.close();  
                            writer.close();  
                            socket.close();  
      
                            // 向所有在线用户发送该用户的下线命令  
                            for (int i = clients.size() - 1; i >= 0; i--) {  
                                clients.get(i).getWriter().println(  
                                        "DELETE@" + user.getName());  
                                clients.get(i).getWriter().flush();  
                            }  
      
                            listModel.removeElement(user.getName());// 更新在线列表  
      
                            // 删除此条客户端服务线程  
                            for (int i = clients.size() - 1; i >= 0; i--) {  
                                if (clients.get(i).getUser() == user) {  
                                    ClientThread temp = clients.get(i);  
                                    clients.remove(i);// 删除此用户的服务线程  
                                    temp.stop();// 停止这条服务线程  
                                    return;  
                                }  
                            }  
                        } else {  
                            dispatcherMessage(message);// 转发消息  
                        }  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
      
            // 转发消息  
            public void dispatcherMessage(String message) {  
                StringTokenizer stringTokenizer = new StringTokenizer(message, "@");  
                String source = stringTokenizer.nextToken();  
                String owner = stringTokenizer.nextToken();  
                String content = stringTokenizer.nextToken();  
                message = source + "说:" + content;  
                contentArea.append(message + "\r\n");  
                if (owner.equals("ALL")) {// 群发  
                    for (int i = clients.size() - 1; i >= 0; i--) {  
                        clients.get(i).getWriter().println(message + "(多人发送)");  
                        clients.get(i).getWriter().flush();  
                    }  
                }  
            }  
        }  
    }  

    Client(客户端):

    import java.awt.BorderLayout;  
    import java.awt.Color;  
    import java.awt.GridLayout;  
    import java.awt.Toolkit;  
    import java.awt.event.ActionEvent;  
    import java.awt.event.ActionListener;  
    import java.awt.event.WindowAdapter;  
    import java.awt.event.WindowEvent;  
    import java.io.BufferedReader;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.io.PrintWriter;  
    import java.net.Socket;  
    import java.util.HashMap;  
    import java.util.Map;  
    import java.util.StringTokenizer;  
      
    import javax.swing.DefaultListModel;  
    import javax.swing.JButton;  
    import javax.swing.JFrame;  
    import javax.swing.JLabel;  
    import javax.swing.JList;  
    import javax.swing.JOptionPane;  
    import javax.swing.JPanel;  
    import javax.swing.JScrollPane;  
    import javax.swing.JSplitPane;  
    import javax.swing.JTextArea;  
    import javax.swing.JTextField;  
    import javax.swing.border.TitledBorder;  
      
    public class Client{  
      
        private JFrame frame;  
        private JList userList;  
        private JTextArea textArea;  
        private JTextField textField;  
        private JTextField txt_port;  
        private JTextField txt_hostIp;  
        private JTextField txt_name;  
        private JButton btn_start;  
        private JButton btn_stop;  
        private JButton btn_send;  
        private JPanel northPanel;  
        private JPanel southPanel;  
        private JScrollPane rightScroll;  
        private JScrollPane leftScroll;  
        private JSplitPane centerSplit;  
      
        private DefaultListModel listModel;  
        private boolean isConnected = false;  
      
        private Socket socket;  
        private PrintWriter writer;  
        private BufferedReader reader;  
        private MessageThread messageThread;// 负责接收消息的线程  
        private Map<String, User> onLineUsers = new HashMap<String, User>();// 所有在线用户  
      
        // 主方法,程序入口  
        public static void main(String[] args) {  
            new Client();  
        }  
      
        // 执行发送  
        public void send() {  
            if (!isConnected) {  
                JOptionPane.showMessageDialog(frame, "还没有连接服务器,无法发送消息!", "错误",  
                        JOptionPane.ERROR_MESSAGE);  
                return;  
            }  
            String message = textField.getText().trim();  
            if (message == null || message.equals("")) {  
                JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",  
                        JOptionPane.ERROR_MESSAGE);  
                return;  
            }  
            sendMessage(frame.getTitle() + "@" + "ALL" + "@" + message);  
            textField.setText(null);  
        }  
      
        // 构造方法  
        public Client() {  
            textArea = new JTextArea();  
            textArea.setEditable(false);  
            textArea.setForeground(Color.blue);  
            textField = new JTextField();  
            txt_port = new JTextField("6666");  
            txt_hostIp = new JTextField("127.0.0.1");  
            txt_name = new JTextField("xiaoqiang");  
            btn_start = new JButton("连接");  
            btn_stop = new JButton("断开");  
            btn_send = new JButton("发送");  
            listModel = new DefaultListModel();  
            userList = new JList(listModel);  
      
            northPanel = new JPanel();  
            northPanel.setLayout(new GridLayout(1, 7));  
            northPanel.add(new JLabel("端口"));  
            northPanel.add(txt_port);  
            northPanel.add(new JLabel("服务器IP"));  
            northPanel.add(txt_hostIp);  
            northPanel.add(new JLabel("姓名"));  
            northPanel.add(txt_name);  
            northPanel.add(btn_start);  
            northPanel.add(btn_stop);  
            northPanel.setBorder(new TitledBorder("连接信息"));  
      
            rightScroll = new JScrollPane(textArea);  
            rightScroll.setBorder(new TitledBorder("消息显示区"));  
            leftScroll = new JScrollPane(userList);  
            leftScroll.setBorder(new TitledBorder("在线用户"));  
            southPanel = new JPanel(new BorderLayout());  
            southPanel.add(textField, "Center");  
            southPanel.add(btn_send, "East");  
            southPanel.setBorder(new TitledBorder("写消息"));  
      
            centerSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftScroll,  
                    rightScroll);  
            centerSplit.setDividerLocation(100);  
      
            frame = new JFrame("客户机");  
            // 更改JFrame的图标:  
            frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));  
            frame.setLayout(new BorderLayout());  
            frame.add(northPanel, "North");  
            frame.add(centerSplit, "Center");  
            frame.add(southPanel, "South");  
            frame.setSize(600, 400);  
            int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
            int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
            frame.setLocation((screen_width - frame.getWidth()) / 2,  
                    (screen_height - frame.getHeight()) / 2);  
            frame.setVisible(true);  
      
            // 写消息的文本框中按回车键时事件  
            textField.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent arg0) {  
                    send();  
                }  
            });  
      
            // 单击发送按钮时事件  
            btn_send.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    send();  
                }  
            });  
      
            // 单击连接按钮时事件  
            btn_start.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    int port;  
                    if (isConnected) {  
                        JOptionPane.showMessageDialog(frame, "已处于连接上状态,不要重复连接!",  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                        return;  
                    }  
                    try {  
                        try {  
                            port = Integer.parseInt(txt_port.getText().trim());  
                        } catch (NumberFormatException e2) {  
                            throw new Exception("端口号不符合要求!端口为整数!");  
                        }  
                        String hostIp = txt_hostIp.getText().trim();  
                        String name = txt_name.getText().trim();  
                        if (name.equals("") || hostIp.equals("")) {  
                            throw new Exception("姓名、服务器IP不能为空!");  
                        }  
                        boolean flag = connectServer(port, hostIp, name);  
                        if (flag == false) {  
                            throw new Exception("与服务器连接失败!");  
                        }  
                        frame.setTitle(name);  
                        JOptionPane.showMessageDialog(frame, "成功连接!");  
                    } catch (Exception exc) {  
                        JOptionPane.showMessageDialog(frame, exc.getMessage(),  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                    }  
                }  
            });  
      
            // 单击断开按钮时事件  
            btn_stop.addActionListener(new ActionListener() {  
                public void actionPerformed(ActionEvent e) {  
                    if (!isConnected) {  
                        JOptionPane.showMessageDialog(frame, "已处于断开状态,不要重复断开!",  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                        return;  
                    }  
                    try {  
                        boolean flag = closeConnection();// 断开连接  
                        if (flag == false) {  
                            throw new Exception("断开连接发生异常!");  
                        }  
                        JOptionPane.showMessageDialog(frame, "成功断开!");  
                    } catch (Exception exc) {  
                        JOptionPane.showMessageDialog(frame, exc.getMessage(),  
                                "错误", JOptionPane.ERROR_MESSAGE);  
                    }  
                }  
            });  
      
            // 关闭窗口时事件  
            frame.addWindowListener(new WindowAdapter() {  
                public void windowClosing(WindowEvent e) {  
                    if (isConnected) {  
                        closeConnection();// 关闭连接  
                    }  
                    System.exit(0);// 退出程序  
                }  
            });  
        }  
      
        /**  
         * 连接服务器  
         *   
         * @param port  
         * @param hostIp  
         * @param name  
         */  
        public boolean connectServer(int port, String hostIp, String name) {  
            // 连接服务器  
            try {  
                socket = new Socket(hostIp, port);// 根据端口号和服务器ip建立连接  
                writer = new PrintWriter(socket.getOutputStream());  
                reader = new BufferedReader(new InputStreamReader(socket  
                        .getInputStream()));  
                // 发送客户端用户基本信息(用户名和ip地址)  
                sendMessage(name + "@" + socket.getLocalAddress().toString());  
                // 开启接收消息的线程  
                messageThread = new MessageThread(reader, textArea);  
                messageThread.start();  
                isConnected = true;// 已经连接上了  
                return true;  
            } catch (Exception e) {  
                textArea.append("与端口号为:" + port + "    IP地址为:" + hostIp  
                        + "   的服务器连接失败!" + "\r\n");  
                isConnected = false;// 未连接上  
                return false;  
            }  
        }  
      
        /**  
         * 发送消息  
         *   
         * @param message  
         */  
        public void sendMessage(String message) {  
            writer.println(message);  
            writer.flush();  
        }  
      
        /**  
         * 客户端主动关闭连接  
         */  
        @SuppressWarnings("deprecation")  
        public synchronized boolean closeConnection() {  
            try {  
                sendMessage("CLOSE");// 发送断开连接命令给服务器  
                messageThread.stop();// 停止接受消息线程  
                // 释放资源  
                if (reader != null) {  
                    reader.close();  
                }  
                if (writer != null) {  
                    writer.close();  
                }  
                if (socket != null) {  
                    socket.close();  
                }  
                isConnected = false;  
                return true;  
            } catch (IOException e1) {  
                e1.printStackTrace();  
                isConnected = true;  
                return false;  
            }  
        }  
      
        // 不断接收消息的线程  
        class MessageThread extends Thread {  
            private BufferedReader reader;  
            private JTextArea textArea;  
      
            // 接收消息线程的构造方法  
            public MessageThread(BufferedReader reader, JTextArea textArea) {  
                this.reader = reader;  
                this.textArea = textArea;  
            }  
      
            // 被动的关闭连接  
            public synchronized void closeCon() throws Exception {  
                // 清空用户列表  
                listModel.removeAllElements();  
                // 被动的关闭连接释放资源  
                if (reader != null) {  
                    reader.close();  
                }  
                if (writer != null) {  
                    writer.close();  
                }  
                if (socket != null) {  
                    socket.close();  
                }  
                isConnected = false;// 修改状态为断开  
            }  
      
            public void run() {  
                String message = "";  
                while (true) {  
                    try {  
                        message = reader.readLine();  
                        StringTokenizer stringTokenizer = new StringTokenizer(  
                                message, "/@");  
                        String command = stringTokenizer.nextToken();// 命令  
                        if (command.equals("CLOSE"))// 服务器已关闭命令  
                        {  
                            textArea.append("服务器已关闭!\r\n");  
                            closeCon();// 被动的关闭连接  
                            return;// 结束线程  
                        } else if (command.equals("ADD")) {// 有用户上线更新在线列表  
                            String username = "";  
                            String userIp = "";  
                            if ((username = stringTokenizer.nextToken()) != null  
                                    && (userIp = stringTokenizer.nextToken()) != null) {  
                                User user = new User(username, userIp);  
                                onLineUsers.put(username, user);  
                                listModel.addElement(username);  
                            }  
                        } else if (command.equals("DELETE")) {// 有用户下线更新在线列表  
                            String username = stringTokenizer.nextToken();  
                            User user = (User) onLineUsers.get(username);  
                            onLineUsers.remove(user);  
                            listModel.removeElement(username);  
                        } else if (command.equals("USERLIST")) {// 加载在线用户列表  
                            int size = Integer  
                                    .parseInt(stringTokenizer.nextToken());  
                            String username = null;  
                            String userIp = null;  
                            for (int i = 0; i < size; i++) {  
                                username = stringTokenizer.nextToken();  
                                userIp = stringTokenizer.nextToken();  
                                User user = new User(username, userIp);  
                                onLineUsers.put(username, user);  
                                listModel.addElement(username);  
                            }  
                        } else if (command.equals("MAX")) {// 人数已达上限  
                            textArea.append(stringTokenizer.nextToken()  
                                    + stringTokenizer.nextToken() + "\r\n");  
                            closeCon();// 被动的关闭连接  
                            JOptionPane.showMessageDialog(frame, "服务器缓冲区已满!", "错误",  
                                    JOptionPane.ERROR_MESSAGE);  
                            return;// 结束线程  
                        } else {// 普通消息  
                            textArea.append(message + "\r\n");  
                        }  
                    } catch (IOException e) {  
                        e.printStackTrace();  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }  
                }  
            }  
        }  
    }  

    User.java

    //用户信息类  
    public class User{  
        private String name;  
        private String ip;  
      
        public User(String name, String ip) {  
            this.name = name;  
            this.ip = ip;  
        }  
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
      
        public String getIp() {  
            return ip;  
        }  
      
        public void setIp(String ip) {  
            this.ip = ip;  
        }  
    }  
About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规