UDP打孔仅部分工作c#

时间:2014-06-06 09:45:00

标签: c# sockets udp hole-punching

我正在尝试使用UDP打孔来进行voip应用程序。我目前正在使用这部分:

  • 打开端口未被服务器上的防火墙阻止(端口转发)
  • 在client1上创建UDP套接字
  • 在client2上创建UDP套接字
  • 将数据包发送到服务器应用程序
  • 服务器发送client1,client2的IP地址和端口,反之亦然
  • 客户端成功接收其他客户端IP地址和端口

现在我在最后阶段遇到了麻烦,这是我目前的代码。我遇到的问题是,虽然我们彼此拥有其他人。 ip地址和端口我们无法互相连接p2p。有没有人有任何建议?

  • ContactIP =从服务器返回的联系人IP地址
  • ContactPort =从服务器返回的contactsPort

    private void PunchHole()
    {
        try
        {
            int range = 10000;
            if ((contactPort - range) < 1000) { contactPort = (contactPort + (range * 2)); }
            //else if ((contactPort + range) >= 65535) { range = range / 2; }
            int port = (contactPort - range);
            byte[] bytesToSend = Encoding.UTF8.GetBytes("Stop");
    
            #region Punch hole through different ports - for loop
            //Console.WriteLine(port);
            for (int i = (contactPort - range); i < 65534; i++)
            {
                if (punchingHole)
                {
                    udpClient.Send(bytesToSend, bytesToSend.Length, contactIP.ToString(), port);
                    port++;
                }
                else { break; }
            }
            if (port >= 65533 && punchingHole)
            {
                range = range * 2;
                port = contactPort - range;
                if (port < 1000) { port = contactPort - (range / 2); }
                for (int i = port; i < 65534; i++)
                {
                    if (punchingHole)
                    {
                        udpClient.Send(bytesToSend, bytesToSend.Length, contactIP.ToString(), port);
                        port++;
                        if (port >= 65533 && (contactPort + 1000) > range) { port = contactPort - range; i = port; continue; }
                    }
                    else { break; }
                }
            }
            if (punchingHole)
            {
                Console.WriteLine("Hole punch unsucessful.");
            }
            #endregion
        }            
        catch (SocketException sockEx) { if (sockEx.SocketErrorCode == SocketError.Interrupted) { } 
                                         else { MessageBox.Show(sockEx.Message, "PunchHole()"); } }
        catch (Exception ex) { MessageBox.Show(ex.Message, "PunchHole()");}            
    }
    
    private void ListeningPort()
    {
        Console.WriteLine("Started Listening");
    
        IPEndPoint listenEP = new IPEndPoint(IPAddress.Any, localPort);
        byte[] messageBytes = udpClient.Receive(ref listenEP);
        punchingHole = false;
        voiceCallEP = new IPEndPoint(listenEP.Address, listenEP.Port);
        message = Encoding.UTF8.GetString(messageBytes);
        Console.WriteLine(message);
        Console.WriteLine(listenEP.Address.ToString().PadRight(30) + listenEP.Port);
        udpClient.Send(messageBytes, messageBytes.Length, voiceCallEP); 
    
        this.Invoke(new MethodInvoker(delegate() { label1.Text = "Hole punched succesfully."; }));
        InitialiseCall();
    }     
    
    • localPort是客户端认为它正在发送的端口(机器的专用端口)
编辑:我一直在修修补补,走到了这个阶段。它确实有效...但我显然经历了所有端口,但这很有效,但这显然是一种糟糕的方式,特别是因为它断开了我用来测试的远程桌面应用程序在不同网络中的计算机上的VOIP应用程序。

1 个答案:

答案 0 :(得分:0)

您不必扫描所有65535端口。您可能会发现,如果您这样做,某些防火墙会阻止您。您的服务器应告知client1 client2的终点(公共IP和端口),反之亦然。

随意在这里使用我的例子: https://github.com/7wingfly/P2Pchat