• udp 内网穿透 互发消息


    还差实现内网终端,向服务器发送请求,要对方的内网连接自己,实现打洞。在同一网段,或者公网运行,可以相互聊天。

    没有实现检测客户端下线功能。

    1,服务器代码

    package router;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
    import java.net.SocketException;
    import java.util.HashSet;
    import java.util.Set;
    
    
    public class Server {
    //    private Set<InetSocketAddress> clients= new HashSet();
        DatagramSocket socket;
        HeartBeat heart;
        
        Server(){
            try {
                socket = new DatagramSocket(9090);
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        public void startServer(){
            try {
                
                while(true){
                    byte[] buf = new byte[1024];
                    
                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
                    socket.receive(packet);
                    InetAddress addr=packet.getAddress();
                    int port = packet.getPort();
                    
                    InetSocketAddress address = new InetSocketAddress(addr,port);
                    heart.add(address);
                    send(heart.getDests(), address);
                    
                    String s = address + " is comming.";
                    notifyClients(s);
                }
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        private void send(Object clients, SocketAddress client) throws IOException {
            ByteArrayOutputStream bous = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bous);
            oos.writeObject(clients);
            oos.flush();
            
            byte[] data= bous.toByteArray();
            DatagramPacket sendip = new DatagramPacket(data, data.length);
            sendip.setSocketAddress(client);
            socket.send(sendip);
            
        }
        
        void notifyClients(String s){
            
            for( SocketAddress client:heart.getDests()){
                try {
                    send(s, client);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } 
            }
        }
        
        public static void main(String[] args) {
            Server server =new Server();
            server.heart = new HeartBeat(server.socket);
            server.startServer();
        }
        
    }
    View Code

    2,客户端

    package router;
    
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
    import java.net.SocketException;
    import java.util.Set;
    
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class Client extends Thread {
        String serverip = "211.100.75.221";//"192.168.11.100";//
        private SocketAddress server = new InetSocketAddress(serverip, 9090);
        DatagramSocket socket;
    
        JTextArea jta_receive = new JTextArea(10, 50);
    
        JComboBox jta_addList = new JComboBox();
    
        public Client() {
            try {
                socket = new DatagramSocket();
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        public void run() {
            try {
    
                while (true) {
                    byte[] buf = new byte[1024];
    
                    DatagramPacket packet = new DatagramPacket(buf, buf.length);
                    socket.receive(packet);
    //                log(new String(buf,buf.length));
                    read(packet.getData());
                }
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
        private void read(byte[] data) throws IOException, ClassNotFoundException {
            ByteArrayInputStream bous = new ByteArrayInputStream(data);
            ObjectInputStream oos = new ObjectInputStream(bous);
            Object obj = oos.readObject();
    
            if (obj instanceof Set) {
                Set<InetSocketAddress> clients = (Set) obj;
                jta_addList.removeAll();
                jta_addList.removeAllItems();
    
                for (InetSocketAddress it : clients) {
                    log(" add item:"+ it);
                    jta_addList.addItem(it);
                }
            }else if(obj instanceof String){
                String ss =(String) obj;
                if(!ss.startsWith("skip")){
                jta_receive.append(ss);
                jta_receive.append("
    ");
                }
            }
        }
    void log(String s){
        System.out.println(s);
    }
        void setUpUI() {
            JFrame jf = new JFrame("p2p test");
            jf.setLayout(new FlowLayout());
            jf.setSize(700, 400);
    
            JButton jb_get = new JButton("get others ip");
            jf.add(jb_get);
            jf.add(jta_addList);
            jb_get.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    sendRequestMsg("getaddress");
    
                }
    
            });
    
            JLabel la_name = new JLabel("received:");
            JLabel la_user = new JLabel("sendto:");
    
            final JTextField jtf_send = new JTextField(20);
            JButton bu_send = new JButton("send");
    
            JScrollPane js = new JScrollPane(jta_receive);
    
            jf.add(la_name);
            jf.add(js);
            jf.add(la_user);
            jf.add(jtf_send);
            jf.add(bu_send);
    
            ActionListener sendListener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    String msg = jtf_send.getText();
                    InetSocketAddress dest = (InetSocketAddress) jta_addList
                            .getSelectedItem();
                    sendP2P(msg, dest);
                    jtf_send.setText("");
                }
    
            };
    
            bu_send.addActionListener(sendListener);
            jtf_send.addActionListener(sendListener);
    
            jf.setVisible(true);
            jf.setDefaultCloseOperation(3);
    
        }
    
        private void sendRequestMsg(String s) {
            try {
                byte[] buf = s.getBytes();
                DatagramPacket packet;
    
                packet = new DatagramPacket(buf, buf.length, server);
    
                socket.send(packet);
    
            } catch (SocketException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        private void sendP2P(String msg, InetSocketAddress dest) {
            try {
                ByteArrayOutputStream bous = new ByteArrayOutputStream();
                ObjectOutputStream oos;
                oos = new ObjectOutputStream(bous);
    
                oos.writeObject(msg);
                oos.flush();
    
                byte[] data = bous.toByteArray();
                DatagramPacket sendip = new DatagramPacket(data, data.length);
                sendip.setSocketAddress(dest);
                socket.send(sendip);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            Client sender = new Client();
            sender.start();
            sender.setUpUI();
    
        }
    
    }
    View Code

    3,心跳类

    package router;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketAddress;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashSet;
    import java.util.Set;
    import java.util.Timer;
    import java.util.TimerTask;
    
    
    public     class HeartBeat {
        private static final long INTERVAL_TIME = 1 * 5 * 1000;
    
        private Timer timer;
        static Set<SocketAddress> dests = new HashSet();
        DatagramSocket socket;
        public HeartBeat(DatagramSocket socket) {
            this.socket = socket;
            
            try {
                this.timer = new Timer();
    
                this.timer.schedule(new ConnSvrTask(), 1000, INTERVAL_TIME);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private class ConnSvrTask extends TimerTask {
    
            public ConnSvrTask() {
                super();
            }
    
            public void run() {
                Set<SocketAddress> tmpDests = new HashSet<SocketAddress>();
                    byte[] b = "skip".getBytes();
                    
                    // 发送心跳
                     println("====heartbeat====");
                    for (SocketAddress dest : dests) {
                        
                        
                            println(dest.toString());
                            sendP2P("skip", dest);
    //                        DatagramPacket packet = new DatagramPacket(b, b.length);
    //                        packet.setSocketAddress(dest);
    //                        socket.send(packet);
                            tmpDests.add(dest);
                        
                    }
                    dests = tmpDests;
            }
        }
    
        private void sendP2P(String msg, SocketAddress dest) {
            try {
                ByteArrayOutputStream bous = new ByteArrayOutputStream();
                ObjectOutputStream oos;
                oos = new ObjectOutputStream(bous);
    
                oos.writeObject(msg);
                oos.flush();
    
                byte[] data = bous.toByteArray();
                DatagramPacket sendip = new DatagramPacket(data, data.length);
                sendip.setSocketAddress(dest);
                socket.send(sendip);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        
        public void add(SocketAddress a){
            dests.add(a);
        }
        public Set<SocketAddress> getDests() {
            return dests;
        }
    
        public void setDests(Set<SocketAddress> dests) {
            this.dests = dests;
        }
        
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd H:m:s");
    
        public void println(String s) {
            System.out.println(format.format(new Date()) + ": " + s);
        }    
    }
    View Code
  • 相关阅读:
    前端学HTTP之重定向和负载均衡
    前端学HTTP之Web主机托管
    前端学HTTP之内容协商
    前端学HTTP之字符集
    前端学HTTP之实体和编码
    前端学HTTP之安全HTTP
    前端学HTTP之摘要认证
    前端学HTTP之基本认证
    前端学HTTP之客户端识别和cookie
    前端学HTTP之网关、隧道和中继
  • 原文地址:https://www.cnblogs.com/bigben0123/p/4710609.html
Copyright © 2020-2023  润新知