UDP打孔只能部分工作c#

Posted

技术标签:

【中文标题】UDP打孔只能部分工作c#【英文标题】:UDP hole punching only partially working c# 【发布时间】:2014-07-27 13:06:45 【问题描述】:

我正在尝试将 UDP 打孔用于 voip 应用程序。我目前有这部分工作:

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

现在我在最后阶段遇到了问题,这是我目前拥有的代码。我遇到的问题是,虽然我们拥有彼此的 IP 地址和端口,但我们无法相互连接 p2p。有人有什么建议吗?

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

ContactPort = 从服务器返回的联系人端口

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 应用程序的远程桌面应用程序不同的网络。

【问题讨论】:

呃,你的实际问题/疑问是什么? 您好,抱歉,不清楚。我遇到的问题是我们现在有了彼此的 ip 地址,但我们无法相互连接 p2p。 您必须保持间隔发送,直到收到另一端的答复。一条消息是不够的。 谢谢,所以我应该发送到 1000 以上的所有端口,直到它收到一个?还是应该对我从服务器收到的端口做 100~ 的任何一种方式? 我已将 uPnP 添加到我的应用程序中,它现在可以完全正常工作,但我仍然希望 UDP 打孔正常工作,因为很多人会担心在他们的路由器上启用 uPnP,所以我需要打孔才能在禁用 uPnP 的情况下工作。但是,如果至少有一个呼叫者启用了 uPnP,它就会起作用。 【参考方案1】:

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

请随意使用我的示例: https://github.com/7wingfly/P2Pchat

【讨论】:

以上是关于UDP打孔只能部分工作c#的主要内容,如果未能解决你的问题,请参考以下文章

UDP打孔不成功,但测试表明它应该可以工作(移动网络)

UDP打孔无法外接

UDP打孔混乱

需要帮助设置用于 p2p 数据传输的 udp 打孔。无法让 STUN 工作

UDP打孔:单机可测试性

1个端口上的UDP打孔?