es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo conectar dos clientes Java que están utilizando STUN para evitar NATs en una conexión P2P?

He estado trabajando en un proyecto de intercambio de archivos de igual a igual en Java y he llegado a un muro del que no tengo ni idea de cómo desmontarlo. Tengo 2 clientes que ejecutan un código idéntico, ambos detrás de NATs (probablemente, aunque no simétricos), que han accedido a su dirección IP pública y puerto a través de un servidor STUN. Cuando intento hacer una conexión entre ellos, no recibo ninguna respuesta y el cliente receptor no registra ningún intento de conexión. Este problema no ocurrió con el mismo código usando direcciones IP locales.

Código de conexión relevante:

PeerConnection peerConn = new PeerConnection(pd);
            PeerMessage toSend = new PeerMessage(msgType, msgData);
            peerConn.sendData(toSend);

        if (waitReply) {
            PeerMessage oneReply = peerConn.receiveData();
            while (oneReply != null) {
                msgReply.add(oneReply);
                oneReply = peerConn.receiveData();
            }
        }

        peerConn.close();
public class PeerConnection {
private final PeerInfo pd;
private SocketInterface s;

public PeerConnection(PeerInfo info) throws IOException {
    pd = info;
    s = NormalSocketFactory.makeSocket(pd.getHost(), pd.getPort());
}
public void sendData(PeerMessage msg){ s.write(msg.toBytes()); }
public PeerMessage receiveData(){ return new PeerMessage(s); }
public void close() {if (s != null){ s.close(); s = null; } }

Se omiten los comentarios adicionales / try-catch y otros fragmentos de código por brevedad.

Estoy pasando manualmente la dirección IP y el puerto que me ha dado un servidor STUN (para fines de prueba) en esta conexión entre pares, y otro código está creando los datos reales (tipo de conexión a quién se está conectando, etc.), pero no creo que el contenido tenga ninguna relación con esto, ya que puede manejar los paquetes de entrada que se crean (como se ha verificado mediante pruebas de LAN).

¿Me estoy perdiendo algo aquí? Los clientes están sentados escuchando un paquete pero no los están recibiendo. Usando WireShark (un programa que admito soy completamente nuevo), puedo ver que las conexiones se están restableciendo (específicamente que se establece la bandera de restablecimiento, algo que de ninguna manera hago).

No tengo un servidor de señalización que maneje esto ya que no tengo planes para alojar nada por el momento, pero no entiendo mucho cómo no habría encontrado un problema similar con eso.

EDITAR: Después de usar WaifUPnP para permitir que los puertos se abran a través de los firewalls, todavía tuve problemas con la mayoría de las conexiones que intenté probar. No sé si este es un problema NAT simétrico, pero se han realizado algunas conexiones. No voy a eliminar esto en caso de que alguien lo necesite más tarde.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema que estás enfrentando está relacionado con el problema de traversión NAT al usar una red peer-to-peer. NAT básicamente traduce direcciones IP privadas a públicas, lo que hace difícil la comunicación directa entre dos clientes detrás de NATs.

    Para superar este problema, se utilizan servidores STUN (Session Traversal Utilities para NAT) para detectar las direcciones IP públicas y los puertos del cliente. Sin embargo, esto solo no es suficiente para establecer una conexión, ya que algunos NAT no son simétricos y no pueden reenviar paquetes entrantes.

    Una solución para esto es implementar un servidor TURN (Traversal Using Relay NAT). Este servidor actúa como intermediario para retransmitir paquetes entre los clientes, permitiéndoles evitar las restricciones de NAT. Otra solución es utilizar el UDP hole punching, que implica el envío de paquetes entre clientes para establecer un canal de comunicación a través de sus NAT.

    En cuanto a tu código, parece que estás utilizando correctamente STUN para obtener las direcciones IP públicas y los puertos de ambos clientes. Sin embargo, no está claro cómo estás intentando establecer la conexión entre ellos. Podría ser un problema con la forma en que se está estableciendo la conexión, o con los NAT mismos.

    Mencionaste el uso de Wireshark para analizar los paquetes que se envían. Parece que las conexiones se están reiniciando, lo que podría indicar un problema de firewall o NAT. También mencionaste el uso de WaifUPnP para abrir puertos a través del firewall, pero esto solo quizás no sea suficiente para resolver el problema.

    En resumen, para establecer una conexión peer-to-peer entre clientes detrás de NAT, necesitas usar STUN para detectar sus direcciones IP públicas y los puertos, e implementar una técnica de traversión NAT como TURN o UDP hole punching. También es importante probar tu código en diferentes configuraciones de NAT para asegurarte de que funcione en todos los escenarios posibles.

Comments are closed.