title: Why does UDP part of RTSP client/server work locally but not remotely? [Java]
body: <p>I made a simple RTSP program (Client and Server) in java to stream audio from an input device to a single client. I tried it locally and it works fine. Then I tried a remote client test and it fails. The the ServerSocket accepts the remote client connection and I can see/get the remote IP using the getInetAddress() method but the UDP part of the program seem to not work as expected.</p>
  
  <p>Here is my code.</p>
  
  <p><strong>Code listing-1</strong>: RTSPServer.java</p>
  
  <pre><code>//imports go here
  
  public class RTSPServer {
  
      public static void main(String args[]) {
          RTSPServer server = new RTSPServer();
          try {
              server.connect(9091);
          } catch (IOException ex) {
              Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
  
      public void connect(int port) throws IOException{
          try (ServerSocket listener = new ServerSocket(port)) {
              while (true) {
                  try (Socket clientSocket = listener.accept()) {
  
  
                      //--------RTSP starts tests here---------
  
                      //--------RTSP ends tests here---------
  
                      //--------UDP streaming starts here---------
  
                      System.out.println(clientSocket.getInetAddress());//print the IP address for debugging purpose
  
                      DatagramSocket RTSPsocket = new DatagramSocket(8300);  //socket for send and receive 
                      RTSPsocket.setSoTimeout(800);//timeout set @ 800ms because ping from VPN server to home &gt; 680ms
                      DatagramPacket udpPacket;
  
                      //InetAddress ClientIPAddr = InetAddress.getLocalHost();//getLocalHost version works locally
                      InetAddress ClientIPAddr = clientSocket.getInetAddress();//getInetAddress doesn't work locally and remotely
                      //InetAddress ClientIPAddr = clientSocket.getLocalAddress();//getLocalAddress only works locally
  
                      AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
                      DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
                      TargetDataLine targetLine = (TargetDataLine)AudioSystem.getLine(info);
                      targetLine.open(format, 40000);
  
                      targetLine.start();
                      byte[] data = new byte[targetLine.getBufferSize()/5];
  
                      while(true){
  
                          targetLine.read(data, 0, data.length);
  
                          RTPPacket rtpPacket = new RTPPacket(0, 0, 0, data, data.length);//make an RTP packet out of the targeLine data
  
                          //retrieve the packet bitstream and store it in an array of bytes
                          byte[] packetBytesArray = new byte[rtpPacket.getlength()];
                          rtpPacket.getpacket(packetBytesArray);
  
                          //send the RTP packet over the UDP socket using datagram packet
                          udpPacket = new DatagramPacket(packetBytesArray, packetBytesArray.length, ClientIPAddr, 8550);
                          RTSPsocket.send(udpPacket);
  
                      }
  
                  } catch (LineUnavailableException ex) {
                      Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
                  }
  
                      //--------UDP streaming ends here---------
              }
  
          } catch (IOException ex) {
              Logger.getLogger(RTSPServer.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
  }
  </code></pre>
  
  <p><strong>Code listing-1</strong>: RTSPClient.java</p>
  
  <pre><code>public class RTSPClient {
  
      //imports go here
  
      private Socket clientSocket;
      private int port;
      private String address;
  
      public static void main(String argv[]) throws Exception
      {
          RTSPClient client = new RTSPClient("my.ip.address.here",9091);
          client.connect();
      }
  
      public RTSPClient(String address, int port){
          this.port = port;
          this.address = address;
      }
  
      public void connect() throws IOException {
          clientSocket = new Socket(address, port);
  
          DatagramSocket udpSocket = null; //socket for send and receive 
          DatagramPacket udpPacket; //UDP packet used to receive packet
          int RTSP_RCV_PORT = 8550; //receiving port for UDP/RTSP
  
          byte[] buf = new byte[8000]; //buffer used to store data received from the server
  
  
          try{
              udpSocket = new DatagramSocket(RTSP_RCV_PORT);
              udpSocket.setSoTimeout(40);//socket timeout 40ms
          }
          catch (SocketException ex)
          {
              System.exit(0);
          }
  
  
  
           //--------RTSP starts tests here---------
  
           //--------RTSP ends tests here---------
  
           //--------UDP streaming starts here---------
  
  
          AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
  
          DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
          SourceDataLine sourceLine = null;
          try {
              sourceLine = (SourceDataLine)AudioSystem.getLine(info);
              sourceLine.open();
          } catch (LineUnavailableException ex) {
              Logger.getLogger(RTSPClient.class.getName()).log(Level.SEVERE, null, ex);
          }
  
  
          if(sourceLine != null){
  
              sourceLine.start();
              boolean makeMeLoop = true;
              while(makeMeLoop){
  
                  udpPacket = new DatagramPacket(buf, buf.length);
  
                  try{
                      //* receive the DP from the socket:
                      udpSocket.receive(udpPacket);
  
                      //* create an RTPpacket object from the DP
                      RTPPacket rtp_packet = new RTPPacket(udpPacket.getData(), udpPacket.getLength());
  
                      //* print important header fields of the RTP packet received:
                      System.out.println("Got RTP packet");
  
                      //* get the payload bitstream from the RTPpacket object
                      int payload_length = rtp_packet.getpayload_length();
                      byte [] payload = new byte[payload_length];
                      rtp_packet.getpayload(payload);
  
                      sourceLine.write(payload, 0, payload.length);
                  }
                  catch (InterruptedIOException ex){
                      System.out.println("Nothing received");
                  }
                  catch (IOException ex) {
                      System.out.println("Exception caught: "+ex);
                  }
              }
          }
  
          clientSocket.close();
      }
  }
  </code></pre>
  
  <p>Since the classes are huge I only left the part of the code that is necessary to troubleshoot the program.</p>
  
  <p><strong>How I've done my remote client test</strong></p>
  
  <p>I ran both code on the same physical machine but the client ran on a virtual machine connected to a VPN proxy. I increased the socket timeout for the RTSPServer's UDP socket because the ping between the VPN server's location and a test server near my location (speedtest.net) was close to 700ms (I am not sure if doing that was relevant). 
  When I connect the remote client to the server the server gives me the remote client's IP address (same address as given in whatismyipaddress.com). So the client is actually connected to the server. But when it comes to send the audio stream, I only get <code>Nothing received</code> messages. Also my computer can be accessed remotely (obviously because the client was able to connect to the server) and every port should be "visible" outside of my LAN (web server can also be accessed, and so on for every ports I've tried).</p>