从文本框中获取的多个端口上的 C# UDP 侦听器

C# UDP listener on multiple ports fetched from text box

我到处找这个问题都没有用。 我想要完成的是在文本框中输入端口列表。 然后我用这些端口创建一个 udpClient 数组开始监听它们。

static class communicator
    {
        // Setting Variables
        static UdpClient[] UDPreceiver;
        static TcpListener[] TCPreceiver;
        static IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
        static bool listening = false;

        // Listener function
        public static void UDPstartlistening(int port)
        {
            // Startlistening
            listening = true;
            while (listening)
            {
                try
                {
                    UDPreceiver[port] = new UdpClient(port); // udp server
                    if (UDPreceiver[port].Available > 0) // Only read if we have some data queued in buffer
                    {
                        //IPEndPoint object will allow us to read datagrams sent from any tracker.
                        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        // Blocks untill data is received
                        Byte[] receiveBytes = UDPreceiver[port].Receive(ref RemoteIpEndPoint);
                        string returnData = ByteArrayToString(receiveBytes);
                        // Uses the IPEndPoint object to determine who sent us anything
                        Program.form1.addlog("Received: " + returnData.ToString() + " - from " + RemoteIpEndPoint.Address.ToString() + " on port: " + RemoteIpEndPoint.Port.ToString());
                        // Forward this message to the website
                        Task.Run(() => forwardToWebsite(returnData.ToString(), RemoteIpEndPoint.Address.ToString(), RemoteIpEndPoint.Port, "udp", port));
                    }
                    Thread.Sleep(10);
                }
                catch (Exception e)
                {
                   MessageBox.Show("Source : " + e.Source + "\r\n" + "Message : " + e.Message, "Error");
                }
            }
        }

它给了我 "Object reference not set to an instance of an object." 行"UDPreceiver[port].Available"。

我这样做的方式正确吗?

我觉得你需要仔细看看网上的例子,你刚刚创建的对象UDPreceiver[port]没有处于接收数据的状态。根据 here 对象应该调用 BeginReceive。没有 C#,但这可能会有所帮助。

试试这个,它包含一些错误修复:

  1. 将您的接收器放在列表中而不是未分配的数组中
  2. 客户端应在读取循环外声明
  3. 您知道这会阻塞调用线程吗? => 使用新线程(()=> { ... });到 运行 另一个线程中的接收部分

代码如下:

static class communicator
{
    // Setting Variables
    static List<UdpClient> UDPreceivers = new List<UdpClient>();
    //static List<TcpListener> TCPreceivers = new List<TcpListener>();
    static IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
    static bool listening = false;

    // Listener function
    public static void UDPstartlistening(int port)
    {
        UdpClient UDPreceiver = new UdpClient(port); // udp server
        UDPreceivers.Add(UDPreceiver);

        // Startlistening
        listening = true;
        while (listening)
        {
            try
            {
                if (UDPreceiver.Available > 0) // Only read if we have some data queued in buffer
                {
                    //IPEndPoint object will allow us to read datagrams sent from any tracker.
                    IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
                    // Blocks untill data is received
                    Byte[] receiveBytes = UDPreceiver.Receive(ref RemoteIpEndPoint);
                    string returnData = ByteArrayToString(receiveBytes);
                    // Uses the IPEndPoint object to determine who sent us anything
                    Program.form1.addlog("Received: " + returnData.ToString() + " - from " + RemoteIpEndPoint.Address.ToString() + " on port: " + RemoteIpEndPoint.Port.ToString());
                    // Forward this message to the website
                    Task.Run(() => forwardToWebsite(returnData.ToString(), RemoteIpEndPoint.Address.ToString(), RemoteIpEndPoint.Port, "udp", port));
                }
                Thread.Sleep(10);
            }
            catch (Exception e)
            {
                MessageBox.Show("Source : " + e.Source + "\r\n" + "Message : " + e.Message, "Error");
            }
        }
    }
}