title: Java: UDP behind NAT
body: <p>i have made a video conferencing application in java. It is based on UDP as it should be. It works well on LAN. Now I am switching it to WAN. After a lot of reading about problems in UDP transmission behind NAT (as there will be users behind different routers). I tried to implement hole punching as read. But its not working. I am using a client-server-client architecture. More precisely, every client sends its images(or frames) to server, which then forwards them to other clients. For this i am using the client's IP and port assigned to them by the router. The server then sends the packets to clients. But the packets are still blocked by the router. Can anyone tell me what should be a reliable solution to this? Or there is any library to achieve hole punching efficiently? </p>
  
  <pre><code>================================================================================== 
  client code:
  //some code
  final Socket client = new Socket(IPaddr, port); // tcp connection 
  ...
  // code for some gui components...
  ...
  String message2="video";
  clientSocketReceiver = new DatagramSocket();
  String ip = "x.x.x.x";
  InetAddress IPAddress = InetAddress.getByName(ip);
  ByteArrayOutputStream baos1 = new ByteArrayOutputStream();    
  baos1.write(message2.getBytes());
  baos1.write('\n');
  baos1.flush();
  byte[] message2InByte = baos1.toByteArray();
  baos1.close();
  clientSocketReceiver.send(new DatagramPacket(message2InByte, message2InByte.length,    IPAddress, 8876));
  ...
  //some code....
  ...
  
  //thread for receiving images..
  while (true) {
        byte[] receiveData = new byte[50000];
        DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
        clientSocketReceiver.receive(receivePacket);
        InputStream in = new ByteArrayInputStream(receivePacket.getData());
        buffImage = ImageIO.read(in);
        ...
        //code for displaying images on GUI
        ...
  }
  //==========================================================================
  
  
  =========================================================================== =
  server code:
  //code for storing client's ip and port. runs only when a new client is accepted by tcp              socket....
  
  serverSocket=new DatagramSocket(8876);       //declared at starting of code
  while (checked==false ) {
         DatagramPacket receivePacket = new  DatagramPacket(receiveData,receiveData.length);
         serverSocket.receive(receivePacket);
         String data = new String(receivePacket.getData());
         data = data.trim();
         if (data.equals("video")) {
               vx.add(receivePacket.getAddress().getHostAddress()); // storing ip
               String tmp = "" + receivePacket.getPort();
               vv.add(tmp);                //storing port. vv and vx r vectors
               checked=true;
         } 
     }
  
  ======================================  
  //thread for receiving/sending images from/to clients
  DatagramSocket serverSocket2 = new DatagramSocket(9876);
  byte[] receiveData = new byte[50000];
  while (true) {
   DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
   serverSocket2.receive(receivePacket);
   InputStream in = new ByteArrayInputStream(receivePacket.getData());
   bImage = ImageIO.read(in);
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   ImageIO.write(bImaget, "jpg", baos);
   baos.flush();
   byte[] imageInByte = baos.toByteArray();
   baos.close();
   for (int i = 0; i &lt; vx.size() &amp;&amp; i &lt; vv.size(); i++) {
       serverSocket2.send(new DatagramPacket(imageInByte, imageInByte.length, InetAddress.getByName(vx.elementAt(i).toString()), Integer.parseInt(vv.elementAt(i).toString())));
    }
  }
  =============================================
  </code></pre>