В чём принцип работы STUN?

Всем, доброго дня! Мне стало интересно, как реализовать передачу данные p2p... Для этого решил использовать tcp/ip протокол. Узнал, что всё объединяется(локальные пк в сети провайдера) в NAT сервера. И чтобы NAT обменивались данные (локальный p2p мне не нужен) есть много путей, но основные:
1. Проброс портов (пробовал Mono.Nat для C#, miniupnp для python) - ничего не сработало
2. STUN сервер, вроде, код, что нашёл в интернете работает, но как-то некорректно, только отправляет, но не получает данные. (ниже приложу код) Но я вот не могу понять, а зачем STUN нужен? Чтобы узнать внешний ip? Так может просто мой друг кинуть, но я законнектиться не смогу, ибо мы просто не найдем друг друга...

Реализация на c# для любопытных

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using LumiSoft.Net.STUN.Client;

namespace Windows_RDR_Host
{
    class Program
    {
        public const string StunServer = "stun4.l.google.com";
        public const int StunServerPort = 19302;
        public static STUN_Result STUN;
        private static Socket socket;

        static void Main(string[] args)
        {
            InitSTUN();
            Console.WriteLine("Your public address: {0}", STUN.PublicEndPoint);

            new Thread(StartSendCycle).Start();
            Console.ReadKey();
        }


        private static void StartSendCycle()
        {
            var data = Encoding.ASCII.GetBytes("Hello, RDP!");

            var sender = new UdpClient(STUN.PublicEndPoint.Port, AddressFamily.InterNetwork);
            sender.AllowNatTraversal(true);

            IPEndPoint ipStun = STUN.PublicEndPoint;

            while (true)
            {
                if (sender.Available > 0)
                {
                    byte[] res = sender.Receive(ref ipStun);

                    Console.WriteLine("Receive: {0}", Encoding.ASCII.GetString(res));
                }

                sender.Send(data, data.Length, STUN.PublicEndPoint);
                Console.WriteLine("Sent " + data.Length + " bytes");
                Thread.Sleep(500);
            }
        }

        public static void InitSTUN()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            socket.Bind(new IPEndPoint(IPAddress.Any, 0));
            STUN = STUN_Client.Query(StunServer, StunServerPort, socket);
        }
    }
}

  • Вопрос задан
  • 6908 просмотров
Решения вопроса 2
@none7
STUN нужен, чтобы узнать свой внешний ip и, что важнее внешний порт ассоциированный с внутренним. Ещё STUN сервер нужен, чтобы выяснить тип NAT. Если у одного из Вас Symmetric, а у другого RestrictedCone или PortRestrictedCone, то можно забыть про P2P. Больше STUN не на что не годен. В случае VoIP, клиенты желающие соединиться обмениваются через SIP адресами полученными через STUN и направляют на друг друга поток трафика. В случае restricted NAT передача должна начаться с обеих сторон иначе NAT принимающей стороны решит, что пакеты нужно отбросить. Teredo например начинает слать пакеты пустышки, получение которых символизирует, что соединение уже установлено. Вы можете написать собственный Teredo клиент по спецификации, она довольно простая.
STUN такой куций протокол потому, что он лишь дополнение для SIP. Но это не мешает использовать его для своих нужд.
Ответ написан
Комментировать
ayazer
@ayazer
Sr. Software Engineer
tcp для p2p требует еще одного stun\turn\ice сервера для проведения хендшейка. иначе никак.

чтоб было чуть понятней в чем проблема - если второй клиент за натом, то внутри адрес у него какой-то 192.168.22.88, а наружу он идет через нат с ипшником 172.22.20.20. проблема в том, что за этим натом может быть еще несколько сотень других компов, каждый с которых (снаружи) виден под этим ипшником. Именно по этой причине попытке законнектится к ипшнику вашего друга заканчивается провалом. нат просто не понимает что с этим запросом делать, потому отбрасывает его.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы