C# 将两个 UDP 客户端连接到一个端口(发送和接收)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9120050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:03:22  来源:igfitidea点击:

Connecting two UDP clients to one port (Send and Receive)

c#portreusabilityudpclient

提问by brooc

I tried the suggestion from this questionwith very little success.

我尝试了这个问题的建议,收效甚微。

Please... any help will be greatly appreciated!

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

Here is my code:

这是我的代码:

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
}

采纳答案by sipwiz

You have to set the socket option before binding.

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

    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();
    }

Or a more illustrative example:

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

    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();
    }

回答by MethodMan

I looked up your error message and this explains what the error is and why it is happening.

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

Here is the exact error message and reason WSAEACCES10013 (MSDN)

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

Permission denied.

An attempt was made to access a socket in a way forbidden by its access permissions. An example is using a broadcast address for sendto without broadcast permission being set using setsockopt(SO_BROADCAST).

Another possible reason for the WSAEACCES error is that when the bind function is called (on Windows NT 4.0 with SP4 and later), another application, service, or kernel mode driver is bound to the same address with exclusive access. Such exclusive access is a new feature of Windows NT 4.0 with SP4 and later, and is implemented by using the SO_EXCLUSIVEADDRUSE option.

没有权限。

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

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

回答by MethodMan

Even changing your code so that I can pass in an IP address I gets the same error message it appears that you can't bind to the same port and only one port can be used here is the sample code I used your example and Altered it to capture my ip from my local machine..

即使更改您的代码以便我可以传入 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

this will produce the exception on the Bind () method.. sorry.

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

回答by naXa

To solve WSAEACCESS 10013 (MSDN) exception in UDP application you can try

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

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