当前位置: 代码迷 >> J2EE >> 局域网聊天工具,该怎么处理
  详细解决方案

局域网聊天工具,该怎么处理

热度:280   发布时间:2016-04-22 03:39:42.0
局域网聊天工具
下午在公司闲的蛋疼,花了2个小时整了个局域网的聊天工具玩。界面模仿飞鸽传书,基于UDP协议,只有最基本的聊天功能。代码结构也比较乱,有兴趣的可以拿去玩玩。
Java code
import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;import java.net.SocketException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Hashtable;import java.util.Map;import java.util.UUID;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JScrollPane;import javax.swing.JTable;import javax.swing.JTextArea;import javax.swing.JButton;import javax.swing.border.EtchedBorder;import javax.swing.table.DefaultTableModel;import java.awt.SystemColor;import javax.swing.ScrollPaneConstants;import java.awt.Color;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JLabel;public class Msg extends JFrame {    private static final long serialVersionUID = 3170335398335303363L;    private String uname = "qq";    private DatagramSocket server;// UDP    private InetAddress broadcastAddress;// 廣播地址    private int port;// 監聽端口    private final Map<String, UserInfo> userTable = new Hashtable<String, UserInfo>();// 用戶列表    private final String guid = UUID.randomUUID().toString().replace("-", "").toUpperCase();// 本機唯一標識    private JTable table;    private JTextArea textArea;    private JLabel lblNewLabel_1;    public Msg() throws SocketException {        this(5413);    }    public Msg(int port) throws SocketException {        this.port = port;        getContentPane().setLayout(null);        getContentPane().setBackground(SystemColor.control);        JButton btnNewButton = new JButton("刷新");        btnNewButton.addMouseListener(new MouseAdapter() {            public void mouseClicked(MouseEvent e) {                refresh();            }        });        btnNewButton.setBackground(SystemColor.control);        btnNewButton.setBounds(299, 119, 83, 28);        getContentPane().add(btnNewButton);        JScrollPane scrollPane = new JScrollPane();        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);        scrollPane.setBounds(12, 12, 275, 135);        getContentPane().add(scrollPane);        table = new JTable(new DefaultTableModel(new Object[][] { { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, { null, null, null }, }, new String[] { "\u7528\u6236\u540D", "IP", "GUID" }) {            private static final long serialVersionUID = -6259343924352571655L;            public boolean isCellEditable(int row, int column) {                return false;            }        });        table.setBackground(new Color(255, 255, 255));        scrollPane.setViewportView(table);        table.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));        JScrollPane scrollPane_1 = new JScrollPane();        scrollPane_1.setBounds(12, 159, 370, 104);        getContentPane().add(scrollPane_1);        textArea = new JTextArea();        textArea.setLineWrap(true);        textArea.addKeyListener(new KeyAdapter() {            public void keyPressed(KeyEvent e) {                if ((e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) || (e.isAltDown() && e.getKeyCode() == KeyEvent.VK_S)) {                    sendMessage();                }            }        });        scrollPane_1.setViewportView(textArea);        JButton button = new JButton("發送");        button.setBackground(SystemColor.control);        button.setBounds(141, 275, 83, 28);        button.addMouseListener(new MouseAdapter() {            public void mouseClicked(MouseEvent e) {                sendMessage();            }        });        getContentPane().add(button);        JButton button_1 = new JButton("關閉");        button_1.setBackground(SystemColor.control);        button_1.setBounds(22, 275, 83, 28);        button_1.addMouseListener(new MouseAdapter() {            public void mouseClicked(MouseEvent e) {                Msg.this.dispatchEvent(new WindowEvent(Msg.this, WindowEvent.WINDOW_CLOSING));            }        });        getContentPane().add(button_1);        JLabel lblNewLabel = new JLabel("當前在線人數");        lblNewLabel.setBounds(299, 29, 83, 18);        getContentPane().add(lblNewLabel);        lblNewLabel_1 = new JLabel("0");        lblNewLabel_1.setBounds(305, 59, 55, 18);        getContentPane().add(lblNewLabel_1);                JLabel lblNewLabel_2 = new JLabel("Alt+S或Ctrl+Enter發送");        lblNewLabel_2.setBounds(242, 280, 140, 18);        getContentPane().add(lblNewLabel_2);        this.setSize(400, 348);        setBackground(SystemColor.control);        setResizable(false);        setTitle("局域網聊天");        this.setLocationRelativeTo(null);        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                try {                    sendBroadcast((guid + "2").getBytes(), broadcastAddress);                } catch (Exception e2) {                }            }        });        try {            uname = JOptionPane.showInputDialog("請輸入你的暱稱");            uname = uname == null ? "匿名" : uname;            server = new DatagramSocket(port);            broadcastAddress = InetAddress.getByName("255.255.255.255");            new AcceptBroadcastThread().start();// 啟動監聽            sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 發送全網廣播,通知上線        } catch (Exception e) {            JOptionPane.showMessageDialog(this, "端口" + port + "被佔用!");            System.exit(0);        }    }    /**     * 向外發送數據     *      * @param data     * @param address     * @throws IOException     */    public void sendBroadcast(byte[] data, InetAddress address) throws IOException {        DatagramPacket dp = new DatagramPacket(data, data.length, address, port);        server.send(dp);    }    /**     * 刷新列表     */    public void refresh() {        // 清空列表        userTable.clear();        DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());        for (int j = table.getRowCount(); j > 0; j--) {            tableModel.removeRow(j - 1);        }        try {            sendBroadcast((guid + "3" + uname).getBytes(), broadcastAddress);// 重新發送全網廣播,通知上線        } catch (Exception e) {        }    }    public void alertMessage(final String msg) {        new Thread() {            public void run() {                JOptionPane.showMessageDialog(Msg.this, msg);            };        }.start();    }    /**     * 發送文字消息     */    public void sendMessage() {        int[] selectRows = table.getSelectedRows();        DefaultTableModel tableModel = (DefaultTableModel) table.getModel();        String msg = guid + "1" + textArea.getText();        byte[] data = string2Bytes(msg);        for (int i = 0, j = selectRows.length; i < j; i++) {            String key = (String) tableModel.getValueAt(selectRows[i], 2);            UserInfo ui = key == null ? null : userTable.get(key);            if (ui != null) {                try {                    textArea.setText("");                    sendBroadcast(data, ui.getIpAddress());                } catch (Exception e) {                    JOptionPane.showMessageDialog(this, "發送消息到" + ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")失敗!", "發送失敗", JOptionPane.ERROR_MESSAGE);                }            }        }    }    private byte[] string2Bytes(String str) {        try {            return str.getBytes("UTF-8");        } catch (Exception e) {        }        return null;    }    class UserInfo {        private String guid;        private String name;        private InetAddress ipAddress;        public String getGuid() {            return guid;        }        public void setGuid(String guid) {            this.guid = guid;        }        public String getName() {            return name;        }        public void setName(String name) {            this.name = name;        }        public InetAddress getIpAddress() {            return ipAddress;        }        public void setIpAddress(InetAddress ipAddress) {            this.ipAddress = ipAddress;        }    }    class AcceptBroadcastThread extends Thread {        public void run() {            while (true) {                try {                    DatagramPacket dp = new DatagramPacket(new byte[1024], 1024);                    server.receive(dp);                    String msg = new String(dp.getData(), 0, dp.getLength(), "UTF-8");// 解析廣播數據包                    String uid = msg.substring(0, 32);                    String type = msg.substring(32, 33);                    if (type.equals("0") || type.equals("3")) {                        UserInfo ui = new UserInfo();                        ui.setGuid(uid);                        ui.setName(msg.substring(33));                        ui.setIpAddress(dp.getAddress());                        // 刷新請求,只響應不做其他處理                        if (userTable.containsKey(ui.getGuid()) && type.equals("3")) {                            sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);                        }                        // 上線通知                        if (!userTable.containsKey(ui.getGuid())) {                            userTable.put(ui.getGuid(), ui);// 將新用戶添加到用戶表                            lblNewLabel_1.setText("" + userTable.size());                            sendBroadcast((guid + "0" + uname).getBytes(), broadcastAddress);// 響應非本機廣播                            ((DefaultTableModel) table.getModel()).insertRow(0, new String[] { ui.getName(), ui.getIpAddress().getHostAddress(), ui.getGuid() });                        }                    } else if (type.equals("1")) {                        UserInfo ui = userTable.get(uid);                        alertMessage(ui.getName() + "(" + ui.getIpAddress().getHostAddress() + ")-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\r\n" + msg.substring(33));                    } else {                        userTable.remove(uid);// 移除用戶                        lblNewLabel_1.setText("" + userTable.size());                        DefaultTableModel tableModel = ((DefaultTableModel) table.getModel());                        for (int i = 0, j = table.getRowCount(); i < j; i++) {                            if (tableModel.getValueAt(i, 2).equals(uid)) {                                tableModel.removeRow(i);                            }                        }                    }                } catch (Exception e) {                }            }        }    }    public static void main(String[] args) throws Exception {        Msg msg = new Msg();        msg.setVisible(true);    }}