c# - Programando la aplicación P2P
.net sockets (5)
Estoy escribiendo un programa p2p personalizado que se ejecuta en el puerto 4900. En algunos casos, cuando la persona está detrás de un enrutador, este puerto no es accesible desde Internet.
¿Existe una forma automática de habilitar el acceso al puerto desde Internet? No estoy seguro de cómo funcionan otras aplicaciones p2p.
¿Alguien puede arrojar algo de luz sobre esto?
Conectividad P2P en pocas palabras. Supongamos que estamos hablando de UDP aquí. Los pasos a continuación también se pueden aplicar a TCP con algunos ajustes.
Enumere todas sus direcciones IP locales (generalmente solo 1). Cree un socket UDP en un número de puerto ** para cada adaptador con una dirección IP.
Para cada socket creado en el paso 1, póngase en contacto con un servidor STUN o TURN con el mismo socket para descubrir su dirección IP externa y descubrir a qué se asigna el número de puerto interno fuera de NAT (no siempre es el mismo valor de puerto). Es decir, su dirección local 192.168.1.2:4900 podría ser 128.11.12.13:8888 para el mundo exterior. Y algunos NAT no siempre usan la misma asignación de puertos cuando usan el mismo puerto local para otras direcciones IP. TURN también te proporcionará una "dirección de relevo". También puede usar UPNP para obtener una dirección asignada al puerto directamente desde su enrutador, si es compatible con ese protocolo.
A través de un servicio de encuentro (SIP, XMPP, mensaje instantáneo, servicio web, correo electrónico, tazas con cadenas), publique su lista de candidatos de direcciones en un servicio o envíe una notificación al otro cliente que diga: "Hola, quiero conectarme con usted". ". Este mensaje incluye todos los "candidatos de dirección" (pares de puerto e IP) recopilados en los pasos 1 y 2.
El cliente remoto, al recibir la invitación para conectarse, realiza los pasos 1 y 2 anteriores también. Luego devuelve su lista de candidatos a través del mismo canal en el que recibió la lista de candidatos del invitador.
Paso de perforado. Ambos clientes comienzan a enviar mensajes de prueba a través de UDP a los candidatos de dirección del otro lado y escuchan los mismos mensajes en su extremo. Siempre que se reciba un mensaje, responda de nuevo a la dirección de la que proviene. Eventualmente, los clientes descubrirán que tienen un par de direcciones que también pueden enviar datagramas de manera confiable. Típicamente, un punto final toma la decisión final sobre qué par de direcciones (sockets) se comunican y el protocolo facilita que este punto extremo le indique al otro punto final esta decisión.
** - generalmente es mejor no confiar en un puerto bien conocido para clientes P2P. Debido a que dos clientes detrás del mismo NAT o firewall probablemente no puedan usar su software al mismo tiempo.
Aquí hay un resumen rápido de algunas tecnologías para explorar.
STUN : es un servidor y protocolo simple para que los clientes que se encuentran detrás de una ruta NAT / descubran cuáles son sus asignaciones externas de IP y puertos.
TURN es una expansión de STUN, pero admite la retransmisión de escenarios de conectividad P2P donde los firewalls y los NAT impiden las conexiones directas.
ICE es un conjunto de pasos mediante los cuales STUN y TURN se usan para configurar una conexión P2P. ICE es un protocolo formal para los pasos 1-5 anteriores. Dos excelentes juegos de diapositivas en ICE están here y here .
WebRTC es una variante del estándar ICE, así como una biblioteca de referencia para realizar sesiones P2P con STUN y TURN.
UPNP + Protocolo de dispositivo de puerta de enlace de Internet : algunos enrutadores admiten esto para que los hosts obtengan automáticamente las asignaciones de puertos.
libnice es una biblioteca C de código abierto para Linux (y podría funcionar en Windows) que implementa ICE.
libjingle es otra implementación de ICE (en C ++) de Google. Para Windows y Linux.
PJNATH es una biblioteca dentro del conjunto de bibliotecas de codificación PJSIP . Es una buena implementación de una pila ICE (código C) y ha sido portada a muchas plataformas. (Windows, Linux, Mac, iOS, Symbian y pronto Android).
Y finalmente, tengo un enchufe descarado para que pueda usar mi base de código de servidor STUN .
Esto puede ser un poco más complicado de lo que está buscando, pero TCP Hole Punching es una técnica que debería funcionar. http://en.wikipedia.org/wiki/TCP_hole_punching
Alternativamente, UPnP funciona muy bien para los enrutadores / firewalls que lo soportan.
Hay soluciones en algunos casos, vea UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
Mi enrutador doméstico permite esto, básicamente, el NAT se puede configurar automáticamente mediante la solicitud adecuada de la computadora.
No contaría con esto para proporcionar una gran mejora en su disponibilidad, porque no muchos enrutadores lo admiten y lo tienen habilitado.
EDITAR: @David sugirió esta pregunta SO para una biblioteca .NET para UPnP: ¿Hay una biblioteca UPnP para .NET (C # o VB.NET)?
Tiene otra opción que es NAT Protocolo de mapeo de puertos (NAT-PMP) NAT-PMP es ampliamente utilizado por las aplicaciones de VoIP, como los clientes de Skype o BitTorrent P2P.
Utilizaría la tecnología WebRTC como un marco de código abierto para dicha aplicación.
De hecho, es un proyecto de código abierto que admite todo lo necesario para las tecnologías punto a punto de forma inmediata:
- ICE y STUN (NAT transversal)
- DTLS y SRTP (seguridad)
- AVPF para la calidad de transmisión.