【问题标题】:UDP sending / receiving on a free port空闲端口上的 UDP 发送/接收
【发布时间】:2014-10-04 07:28:11
【问题描述】:

在一个项目中,有一个设备侦听特定的 UDP 端口并响应发送者端口。

对于发送方和接收方我希望系统选择一个空闲端口,所以我有以下代码:

[请原谅大量代码,但这是显示发生了什么行为的最小示例]

发送代码:

public class UdpSender
{
    public int Port = 0; // some initially random port
    public UdpClient UdpServer { get; set; }

    public UdpSender()
    {
        UdpServer = CreateUdpClient();

        // save the portnumber chosen by system to reuse it
        Port = ((IPEndPoint)(UdpServer.Client.LocalEndPoint)).Port;
    }

    private UdpClient CreateUdpClient()
    {
        if (UdpServer != null)
        {
            UdpServer.Close();
        }

        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Port);

        var udpServer = new UdpClient();
        udpServer.ExclusiveAddressUse = false;
        udpServer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Client.Bind(localEndPoint);

        return udpServer;
    }

    public void Send(byte[] arr)
    {
        UdpServer = CreateUdpClient();

        int remotePortNumber = 6565;
        var remoteEndPoint = new IPEndPoint(IPAddress.Broadcast, remotePortNumber);

        try
        {
            UdpServer.Send(arr, arr.Length, remoteEndPoint);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        UdpServer.Close();
    }
}

接收代码:

public class UDPListener
{
    private static int portNumber;
    private UdpClient udpClient = null;
    public List<DeviceData> DeviceList = new List<DeviceData>();

    public UDPListener(int port)
    {
        portNumber = port;
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, portNumber);

        udpClient = new UdpClient();
        udpClient.ExclusiveAddressUse = false;

        udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpClient.Client.Bind(localEndPoint);
        udpClient.Client.ReceiveBufferSize = 1 << 23;
    }

    public void StartListening()
    {
        this.udpClient.BeginReceive(Receive, new object());
    }

    private void Receive(IAsyncResult ar)
    {
        IPEndPoint ip = new IPEndPoint(IPAddress.Any, portNumber);
        byte[] bytes = udpClient.EndReceive(ar, ref ip);
        string message = Encoding.ASCII.GetString(bytes);
        DeviceList.Add(new DeviceData(message));
        StartListening();
    }
}

整合:

public class DeviceFinder
{
    public IEnumerable<DeviceData> Find()
    {
        var sender = new UdpSender();
        int port = sender.Port;

        var listener = new UDPListener(port);
        listener.StartListening();

        sender.Send(new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 });

        System.Threading.Thread.Sleep(5000); // wait some time for answers

        return listener.DeviceList;
    }
}

Receive 方法永远不会被这种方法调用。但在 Wireshark 中,我可以看到来自设备的答案。

这种方法有什么问题?

在使用这种方法之前,我使用了一个固定端口,并且还添加了对 CreateUdpClient 的调用。似乎与此有关,但我无法弄清楚。 在我刚刚在接收/发送方法中创建了一个带有固定端口的UdpClient 之前。

以前的版本可以看in this question。这完美地工作。但是我担心如果固定端口已经在使用,它就不起作用,因此这种新方法。

【问题讨论】:

  • 看起来您在发送时仍在使用硬编码端口 (int remotePortNumber = 6565;)
  • 这是设备正在侦听的端口。所以我从端口 11111 发送到 6565(例如),设备将响应端口 11111。

标签: c# sockets networking udp port


【解决方案1】:

只需指定零作为您自己的端口号。绑定或发送时系统会分配一个。源端口号将与数据报一起发送给对等方,由对方回复。

【讨论】:

  • 这正是我所做的。我想在发送方和接收方都使用系统分配的这个端口。但是没有调用 Receive 方法。
  • 就这样吧。你真的是这个意思吗?
  • 目前,我不太明白我相信。如问题中的示例代码所示,第一次调用本地端点端口设置为零 (0)。所以系统会为我分配一个空闲端口。现在我想将该端口用于发送方和接收方。而且,使用问题中的方法,永远不会调用 Receive 方法,这应该由系统在接收到该端口的传入 udp 数据报时完成。这是不起作用的部分。 “So call it”是什么意思?
猜你喜欢
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
相关资源
最近更新 更多