qwerty787788

udp broadcast

Sep 27th, 2014
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.62 KB | None | 0 0
  1. import java.io.IOException;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. import java.net.InetAddress;
  5. import java.net.NetworkInterface;
  6. import java.net.SocketException;
  7. import java.net.UnknownHostException;
  8. import java.util.ArrayList;
  9. import java.util.Arrays;
  10. import java.util.Collections;
  11. import java.util.TreeSet;
  12.  
  13. public class Main {
  14.  
  15.     final static int WAIT_TIME = 1000;
  16.     final static int PORT = 7777;
  17.     final static String NAME = "Borys Minaiev";
  18.     final static int SECONDS_WAIT = 20;
  19.     static int myIP = 0;
  20.  
  21.     static class Connection implements Comparable<Connection> {
  22.         String mac;
  23.         String name;
  24.         String ip;
  25.         private int lost;
  26.         private TreeSet<Long> messages;
  27.         private long startTime;
  28.  
  29.         Connection() {
  30.             messages = new TreeSet<>();
  31.             startTime = System.currentTimeMillis();
  32.         }
  33.  
  34.         void addMessage(String mac, String name, String ip) {
  35.             long currentTime = System.currentTimeMillis();
  36.             removeAllUnused();
  37.             messages.add(currentTime);
  38.             this.mac = mac;
  39.             this.name = name;
  40.             this.ip = ip;
  41.         }
  42.  
  43.         private void removeAllUnused() {
  44.             long currentTime = System.currentTimeMillis();
  45.             while (messages.size() > 0) {
  46.                 long last = messages.pollFirst();
  47.                 if (last > currentTime - 1000 * SECONDS_WAIT) {
  48.                     messages.add(last);
  49.                     break;
  50.                 }
  51.             }
  52.         }
  53.  
  54.         public void updateLost() {
  55.             removeAllUnused();
  56.             int need = (int) Math.min(10,
  57.                     (System.currentTimeMillis() - startTime) / WAIT_TIME);
  58.             lost = Math.max(0, need - messages.size());
  59.         }
  60.  
  61.         @Override
  62.         public int compareTo(Connection o) {
  63.             updateLost();
  64.             o.updateLost();
  65.             return Integer.compare(lost, o.lost);
  66.         }
  67.     }
  68.  
  69.     static class Sender implements Runnable {
  70.         byte[] mac;
  71.         byte[] ip;
  72.         DatagramSocket socket;
  73.  
  74.         Sender(byte[] mac, byte[] ip, DatagramSocket socket) {
  75.             this.mac = mac;
  76.             this.ip = ip;
  77.             this.socket = socket;
  78.         }
  79.  
  80.         @Override
  81.         public void run() {
  82.             final byte[] myMessage = createMessage(mac, ip);
  83.             while (true) {
  84.                 DatagramPacket packet = null;
  85.                 try {
  86.                     packet = new DatagramPacket(myMessage, myMessage.length,
  87.                             InetAddress.getByName("255.255.255.255"), PORT);
  88.                 } catch (UnknownHostException e2) {
  89.                     e2.printStackTrace();
  90.                 }
  91.                 try {
  92.                     socket.send(packet);
  93.                 } catch (IOException e1) {
  94.                     System.out.println("error sending a message");
  95.                 }
  96.                 try {
  97.                     Thread.sleep(WAIT_TIME);
  98.                 } catch (InterruptedException e) {
  99.                     e.printStackTrace();
  100.                 }
  101.             }
  102.         }
  103.     }
  104.  
  105.     static class Receiver implements Runnable {
  106.         DatagramSocket socket;
  107.  
  108.         Receiver(DatagramSocket socket) {
  109.             this.socket = socket;
  110.         }
  111.  
  112.         @Override
  113.         public void run() {
  114.             while (true) {
  115.                 waitForMessages(socket);
  116.             }
  117.         }
  118.  
  119.     }
  120.  
  121.     private static int genIP(byte[] ip) {
  122.         int result = 0;
  123.         for (int i = 0; i < ip.length; i++) {
  124.             result = result << 8;
  125.             result += ip[i];
  126.         }
  127.         return result;
  128.     }
  129.  
  130.     private static byte[] createMessage(byte[] mac, byte[] ip) {
  131.         byte[] result = new byte[4 + 6 + NAME.length() + 1];
  132.         for (int i = 0; i < ip.length; i++) {
  133.             result[i] = ip[i];
  134.         }
  135.         for (int i = 0; i < mac.length; i++) {
  136.             result[ip.length + i] = mac[i];
  137.         }
  138.         for (int i = 0; i < NAME.length(); i++) {
  139.             result[ip.length + mac.length + i] = (byte) NAME.charAt(i);
  140.         }
  141.         return result;
  142.     }
  143.  
  144.     private static String macToString(byte[] mac) {
  145.         StringBuilder result = new StringBuilder();
  146.         for (int i = 0; i < mac.length; i++) {
  147.             result.append(String.format("%02X%s", mac[i],
  148.                     (i < mac.length - 1) ? ":" : ""));
  149.         }
  150.         return result.toString();
  151.     }
  152.  
  153.     private static byte[] subArray(byte[] a, int from, int to) {
  154.         byte[] result = new byte[to - from];
  155.         for (int i = 0; i < result.length; i++) {
  156.             result[i] = a[from + i];
  157.         }
  158.         return result;
  159.     }
  160.  
  161.     private static void decodeMessage(byte[] message) {
  162.         if (message.length < 10)
  163.             return;
  164.         InetAddress ip = null;
  165.         try {
  166.             ip = InetAddress.getByAddress(Arrays.copyOf(message, 4));
  167.         } catch (UnknownHostException e) {
  168.             e.printStackTrace();
  169.         }
  170.         if (genIP(ip.getAddress()) == myIP) {
  171.             return;
  172.         }
  173.         byte[] mac = subArray(message, 4, 10);
  174.         int last = 10;
  175.         while (message[last] != 0) {
  176.             last++;
  177.         }
  178.         String name = new String(subArray(message, 10, last));
  179.         String sIp = ip.toString().substring(1);
  180.         synchronized (allConnections) {
  181.             for (Connection c : allConnections) {
  182.                 if (c.ip.equals(sIp)) {
  183.                     c.addMessage(macToString(mac), name, sIp);
  184.                     return;
  185.                 }
  186.             }
  187.             Connection c = new Connection();
  188.             c.addMessage(macToString(mac), name, sIp);
  189.             allConnections.add(c);
  190.         }
  191.  
  192.     }
  193.  
  194.     private static void waitForMessages(DatagramSocket socket) {
  195.         final int bufLength = 1 << 10;
  196.         byte[] buf = new byte[bufLength];
  197.         DatagramPacket packet = new DatagramPacket(buf, buf.length);
  198.         try {
  199.             socket.receive(packet);
  200.         } catch (IOException e) {
  201.             System.out.println("fail ");
  202.         }
  203.         decodeMessage(packet.getData());
  204.     }
  205.  
  206.     static ArrayList<Connection> allConnections = new ArrayList<>();
  207.  
  208.     private static void printInformation() {
  209.         while (true) {
  210.             synchronized (allConnections) {
  211.                 for (int i = 0; i < allConnections.size(); i++) {
  212.                     Connection cur = allConnections.get(i);
  213.                     cur.updateLost();
  214.                     if (cur.messages.size() == 0) {
  215.                         allConnections.remove(i);
  216.                         i--;
  217.                     }
  218.                 }
  219.                 Collections.sort(allConnections);
  220.                 System.out.println("---------------------------");
  221.                 long currentTime = System.currentTimeMillis();
  222.                 for (Connection c : allConnections) {
  223.                     System.out.println(c.ip + " " + c.mac + " " + c.name + " "
  224.                             + (currentTime - c.messages.last()) + "ms last; "
  225.                             + c.lost + " lost");
  226.                 }
  227.                 System.out.println("---------------------------");
  228.             }
  229.  
  230.             try {
  231.                 Thread.sleep(WAIT_TIME);
  232.             } catch (InterruptedException e) {
  233.                 e.printStackTrace();
  234.             }
  235.         }
  236.     }
  237.  
  238.     @SuppressWarnings("resource")
  239.     private static void runServer(byte[] mac, byte[] ip) {
  240.         DatagramSocket socket = null;
  241.         try {
  242.             socket = new DatagramSocket(PORT);
  243.         } catch (SocketException e1) {
  244.             System.out.println("error creating socket on port: " + PORT);
  245.         }
  246.         new Thread(new Sender(mac, ip, socket)).start();
  247.         new Thread(new Receiver(socket)).start();
  248.         printInformation();
  249.     }
  250.  
  251.     public static void main(String[] args) {
  252.         InetAddress ip;
  253.         try {
  254.             ip = InetAddress.getLocalHost();
  255.             NetworkInterface network = NetworkInterface.getByInetAddress(ip);
  256.             byte[] mac = network.getHardwareAddress();
  257.             myIP = genIP(ip.getAddress());
  258.             runServer(mac, ip.getAddress());
  259.         } catch (UnknownHostException e) {
  260.  
  261.             e.printStackTrace();
  262.  
  263.         } catch (SocketException e) {
  264.  
  265.             e.printStackTrace();
  266.  
  267.         }
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment