2012-04-28 25 views
9

Me parece que los dispositivos Android más nuevos se ejecutan detrás de un NAT, donde la dirección local es un operador interno o una dirección LAN y la dirección pública es la dirección externa asignada por el enrutador o el operador.Android: NAT Traversal?

Sin embargo, los teléfonos más nuevos no devuelven la misma dirección usando NetworkInterface como cuando se accede a un servicio de detección de IP.

Por lo tanto, la conexión a través de SocketChannels P2P inherentemente falla.

¿Hay alguna solución común a este problema diseñada para la plataforma Android? ¿Alguien puede aclarar qué está causando este problema de seguridad similar a NAT?

Cualquier enlace a Java NAT transversal tutoriales o ejemplos (NO ensayos o tesis) también sería apreciado por ser útiles (ya que no estoy muy seguro de cómo implementarlo en Java).

¡Por supuesto, también aceptaré cualquier otra solución que cualquier persona pueda ofrecer!

+2

No existe una NAT interna en los dispositivos Android. Un dispositivo tiene una o varias [interfaces] de red (http://docs.oracle.com/javase/tutorial/networking/nifs/definition.html) y si está escuchando en la correcta puede obtener conexiones desde el exterior (asumiendo tienes el permiso de internet). Si no puede verificar la ruta de red entre la que intenta acceder y su dispositivo. – zapl

+0

NAT no tiene nada que ver con el dispositivo final. El dispositivo solo tiene asignada una dirección IP. Si eso es enrutable o no depende del punto de acceso/servidor DHCP. –

+0

Debe tener algo que ver con el dispositivo final. Cuando se prueba una conexión P2P directa con la dirección de la interfaz de red móvil, funciona bien al conectarse a un dispositivo Android anterior (Epic 4G) pero no al conectarse al Galaxy S2. La dirección de Galaxy devuelta por el método NetworkInterface.getNetWorkInterfaces no coincide con la IP externa, mientras que la Epic 4G sí lo hace. Claramente, algo cambió con la configuración de red de los teléfonos. – bgroenks

Respuesta

0

He logrado establecer tomas simplemente reenviando los enchufes que está utilizando durante la conexión en su enrutador. Funcionó para mí

ACTUALIZACIÓN

Conozca cuál es su dirección IP a través de cmd.exe si su uso de Windows (ipconfig) oa través de una sesión de terminal si tu en Linux (ifconfig). Luego conéctese a través del navegador y debería haber una sección de seguridad. Vaya a reenvío de puerto y abra los puertos que usa al establecer que es ServerSocket y Socket. Use TCP como el protocolo. Tenga en cuenta que esto solo se aplica si está intentando conectarse desde fuera de su wlan.

+0

¿Podría elaborar o dar un ejemplo? Esto parece un concepto interesante. – bgroenks

+0

@ ghostsoldier23 Comprobar mi actualización –

+3

Oh, solo reenvío de puertos? El objetivo de NAT Traversal es evitar eso. – bgroenks

6

Casi todos los teléfonos o PC que toque nunca tendrán una dirección IP pública estática y, por lo tanto, requerirán NAT transversal. No es por el dispositivo; el operador o el ISP ponen los enrutadores entre su dispositivo y la red pública de Internet. Dependiendo de su aplicación, generalmente hay librerías de NAT-transversal que puede usar, como ice4j o STUNT.

+0

¿No funcionan tanto ice4j como STUNT solo UDP? – bgroenks

4

Lo hago en mi propio proyecto y he descubierto que este problema no es tan complicado.

Aquí hay un servidor de eco UDP muy simple en el nodo.js

var dgram = require('dgram'); 

var socket = 
    dgram.createSocket('udp4'); 

socket 
    .on('listening', function() 
    { 
     var address = socket.address(); 
     console.log('socket listening ' + 
      address.address + ':' + address.port); 
    }) 
    .on('error', function(err) 
    { 
     console.log('socket error:\n' + err.stack); 
     socket.close(); 
    }) 
    .on('message', function(message, rinfo) 
    { 
     console.log('message: ' + message + ' from ' + 
      rinfo.address + ':' + rinfo.port); 

     var msg = new Buffer(rinfo.address + ':' + rinfo.port); 
     socket 
      .send(msg, 0, msg.length, 
       rinfo.port, rinfo.address, 
       function(err, bytes) 
       { 
        //socket.close(); 
       }); 

    }) 
    .bind(15000); 

Un cliente de Android sólo tiene que enviar un msg a este servidor de nodo

     System.out.println("UDP hole punching======================="); 

         class IOth extends Thread 
         { 
          @Override 
          public void run() 
          { 

           String sendMsg = "UDP hole punching"; 
           byte[] buf = sendMsg.getBytes(); 
           DatagramPacket packet; 

           System.out.println(HPremoteHost); // node server IP 
           System.out.println(HPremotePort); // 15000 
           try 
           { 
            packet = 
              new DatagramPacket(buf, buf.length, 
                InetAddress.getByName(HPremoteHost), HPremotePort); 

            ds.send(packet); 


           } 
           catch (Exception e) 
           { 
            System.out.println("error================"); 
            System.out.println(e); 
           } 
          } 
         } 

         IOth io00 = new IOth(); 
         io00.start(); 

Android cliente UDP listner obtener msg general y su propio puerto IP global & través UDPholepunching

     class IOLoop extends Thread 
         { 
          @Override 
          public void run() 
          { 
           try 
           { 
            String msg = "Native.UDPserver.open"; 

            SocketAddress sockAddress; 
            String address; 


            byte[] buf = new byte[1024]; 
            DatagramPacket packet = new DatagramPacket(buf, buf.length); 
            while (true) 
            { 
             try 
             { 
              ds.receive(packet); 
              sockAddress = packet.getSocketAddress(); 
              address = sockAddress.toString(); 

              msg = new String(buf, 0, packet.getLength()); 

              System.out.println(msg + " received !!! by " + address); 

              //this case is UDP HolePunching reaction 
              if (address.equals(HPaddress1)) 
              { 
               System.out.println(msg + "hole punched"); 

               //So you can obtain own Global ip& port here. 
               //exchange this information 
               //`remoteHost` `remotePort` to another client 
               //with some method (signaling server) 

              } 
             } 
             catch (IOException e) 
             { 
             } 
            } 

           } 
           catch (Exception e) 
           { 
           } 
          } 
         } 

         IOLoop io00 = new IOLoop(); 
         io00.start(); 

El cliente de Android UDP envía usando el IP de otro cliente remoteHostremotePort

     class IOth extends Thread 
         { 
          @Override 
          public void run() 
          { 

           String sendMsg = "This is a test message"; 
           byte[] buf = sendMsg.getBytes(); 
           DatagramPacket packet; 

           try 
           { 
            packet = 
              new DatagramPacket(buf, buf.length, 
                InetAddress.getByName(remoteHost), remotePort); 

            ds.send(packet); 

           } 
           catch (Exception e) 
           { 

           } 
          } 
         } 

         IOth io00 = new IOth(); 
         io00.start(); 
+0

¡excelente respuesta! asumiendo que funcione (-: – wires

+0

¿Cuál es el propósito del código que publicó? –

+0

El propósito es responder a la pregunta –

Cuestiones relacionadas