【问题标题】:Connecting two UDP clients to one port (Send and Receive)将两个 UDP 客户端连接到一个端口(发送和接收)
【发布时间】:2012-02-25 13:31:03
【问题描述】:

我尝试了this question 的建议,但收效甚微。

请...任何帮助将不胜感激!

这是我的代码:

static void Main(string[] args)
{

    IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

    UdpClient udpServer = new UdpClient(localpt); 
    udpServer.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    UdpClient udpServer2 = new UdpClient();
    udpServer2.Client.SetSocketOption(
        SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

    udpServer2.Client.Bind(localpt); // <<---------- Exception here
}

【问题讨论】:

  • 你遇到了什么异常?
  • @M.Babcock 我收到的异常消息是:“试图以访问权限禁止的方式访问套接字”
  • 您的udpServer 实例在尝试绑定时是否会抛出相同的异常?
  • 似乎您没有遵循问题链接中提供的相同代码示例。我看到 IPAddress.Any, 6000 但是 UdpClient udpServer2 = new UdpClient(5000) ;你为什么不在 Try{} catch{} 中包装这样的东西
  • @M.Babcock 如果我没记错的话,它在使用端点构造时已经绑定。无论如何,我尝试这样做: udpServer.Client.Bind(localpt);在设置套接字选项后立即收到不同的异常消息:“提供了无效参数”

标签: c# port reusability udpclient


【解决方案1】:

要解决 UDP 应用程序中的 WSAEACCESS 10013 (MSDN) 异常,您可以尝试

udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);

【讨论】:

    【解决方案2】:

    我查看了您的错误消息,这解释了错误是什么以及发生的原因。

    这是确切的错误消息和原因 WSAEACCES 10013 (MSDN)

    权限被拒绝。

    试图以一种被其禁止的方式访问套接字 访问权限。一个例子是使用广播地址发送到 没有使用 setsockopt(SO_BROADCAST) 设置广播权限。

    WSAEACCES 错误的另一个可能原因是当绑定 调用函数(在带有 SP4 的 Windows NT 4.0 和更高版本上),另一个 应用程序、服务或内核模式驱动程序绑定到同一个 具有独占访问权限的地址。这种独占访问是一项新功能 Windows NT 4.0 SP4 及更高版本,并通过使用 SO_EXCLUSIVEADDRUSE 选项。

    【讨论】:

    • 谢谢,但我已经找到了这些信息。我的代码使用了 SocketOptionName.ReuseAddress,我认为它本质上是 SO_EXCLUSIVEADDRUSE,但以 .NET 方式。似乎需要其他方法来做到这一点,但我似乎找不到它
    • 我这将是一个很好的谜题..我想我也走在正确的轨道上..我会帮助挖掘更多并尝试代码..这可能很简单即使是最老练的编码员也会过目不忘..
    • 谢谢,我已经看了好几天了...没有运气...这应该是一件非常简单的事情...请尝试运行此代码。
    • 当你调试时,你会得到 0.0.0:6000 的 localpt
    • 这行不通,因为 0.0.0 不是真正的 ip,但无论如何我会在下面发布我的发现,不确定其他人是如何声称他们让它工作的.. 这似乎没有/似乎是可能的
    【解决方案3】:

    你必须在绑定之前设置套接字选项。

        static void Main(string[] args)
        {
            IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);
    
            UdpClient udpServer = new UdpClient();
            udpServer.Client.SetSocketOption(
                SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpServer.Client.Bind(localpt);
    
            UdpClient udpServer2 = new UdpClient();
            udpServer2.Client.SetSocketOption(
                SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    
            udpServer2.Client.Bind(localpt); // <<---------- No Exception here
    
            Console.WriteLine("Finished.");
            Console.ReadLine();
        }
    

    或者一个更具说明性的例子:

        static void Main(string[] args)
        {
            IPEndPoint localpt = new IPEndPoint(IPAddress.Loopback, 6000);
    
            ThreadPool.QueueUserWorkItem(delegate
            {
                UdpClient udpServer = new UdpClient();
                udpServer.ExclusiveAddressUse = false;
                udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                udpServer.Client.Bind(localpt);
    
                IPEndPoint inEndPoint = new IPEndPoint(IPAddress.Any, 0);
                Console.WriteLine("Listening on " + localpt + ".");
                byte[] buffer = udpServer.Receive(ref inEndPoint);
                Console.WriteLine("Receive from " + inEndPoint + " " + Encoding.ASCII.GetString(buffer) + ".");
            });
    
            Thread.Sleep(1000);
    
            UdpClient udpServer2 = new UdpClient();
            udpServer2.ExclusiveAddressUse = false;
            udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpServer2.Client.Bind(localpt);
    
            udpServer2.Send(new byte[] { 0x41 }, 1, localpt);
    
            Console.Read();
        }
    

    【讨论】:

    • 我在这里发布了一个后续问题:stackoverflow.com/questions/9140450/…
    • 为什么你在localpt 上使用BindinEndPoint 上的Receive,有什么不同吗? (如果我在localptReceive 似乎没有任何问题)
    • 使用 inEndPoint 的接收将导致它持有数据包来自的远程套接字。你可以使用 localpt,但是你不会有一个简单的方法来知道你绑定到的本地套接字。
    【解决方案4】:

    即使更改您的代码以便我可以传递 IP 地址,我也会收到相同的错误消息,您似乎无法绑定到同一个端口并且只能使用一个端口 这是我使用您的示例并对其进行更改以从本地计算机捕获我的 ip 的示例代码..

            IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0];
            IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);
    
            //IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);
    
            UdpClient udpServer = new UdpClient(ipLocalEndPoint);
            udpServer.Client.SetSocketOption(
                SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpServer.Connect(ipLocalEndPoint);
            UdpClient udpServer2 = new UdpClient();
            udpServer2.Client.SetSocketOption(
                SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    
            udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here
    

    这将在 Bind () 方法上产生异常。抱歉。

    【讨论】:

    • 必须有办法做到这一点。我的目标是创建一个包含 UDP 打孔的系统。这取决于我可以在发送数据的同一端口上侦听...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    相关资源
    最近更新 更多