【问题标题】:UDP not receiving updated valuesUDP 未收到更新的值
【发布时间】:2015-08-17 17:32:06
【问题描述】:

我的udp 类没有从流中接收到更新的值。设备连续发送数据,当任何警报激活时,它会在流中添加代码并发送更新的值,但除非我重新启动程序,否则我的班级不会收到更新的值。

这是我的UDPListener 课程。

public class 
{
    public static int PORT_NUMBER { get; set; }
    public string IpAddress { get; set; }
    private readonly UdpClient udp;
    public event Action<object, EventArgs> msgChanged;
    IAsyncResult ar_ = null;

    public UDPListener(string ipaddr, int port)
    {
        IpAddress = ipaddr;
        PORT_NUMBER = port;
        udp = new UdpClient(PORT_NUMBER);
        Start();
    }

    public void Start()
    {
        StartListening();
    }

    public void Stop()
    {
        try
        {
            udp.Close();
        }
        catch { /* not necessary */ }
    }

    private void StartListening()
    {
        ar_ = udp.BeginReceive(Receive, new object());
    }

    private void Receive(IAsyncResult ar)
    {
        try
        {
            Thread.Sleep(150);
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse(IpAddress), PORT_NUMBER);
            byte[] bytes = udp.EndReceive(ar, ref ip);
            string message = Encoding.ASCII.GetString(bytes);

            //raise event..
            if (message.StartsWith("S"))
                if (msgChanged != null)
                    msgChanged(message, EventArgs.Empty);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error in UDPListner..." + ex.Message);
        }
        finally
        {
            StartListening();
        }
    }
}

现在程序启动时会发生什么,它将接收数据“S0000..”,但是当警报引发时,数据更改为“S8000..etc”,但是除非我重新启动程序,否则此类会持续接收相同的“S000..”数据班级。

当我在 while 循环中运行 udp 侦听器时,它工作得非常好,它接收更新的流并在警报响起时发生变化。

这是 while 循环 udp 的代码。

while (!StopRunning)
{
    Thread.Sleep(150);
    udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);
    var ep = default(IPEndPoint);
    var data = udp.Receive(ref ep);
    udp.Close();
    string msg = Encoding.ASCII.GetString(data);
    if (msgChanged != null)
        msgChanged(msg, EventArgs.Empty);
}

但是我不能使用 while 循环,因为我必须在窗口服务中安装这个程序。

【问题讨论】:

  • 两个问题。首先,你的异步回调中Thread.Sleep 的目的是什么?其次,你确定回调实际上被执行了多次吗?当发件人发送“S8000”时,您的客户端似乎不太可能收到“S0000”。
  • 另请参阅stackoverflow.com/questions/7266101/… 以获得简单的 UDP 接收器。
  • 我只是添加了 thread.sleep 以中断 150 毫秒,因此我开始接收准确的数据。我已经在答案stackoverflow.com/questions/7266101/… 中看到了您的 cmets,并且基于这些建议,我删除了 Thread.sleep 并在 endreceive 之后立即调用 BeginReceive 但它的工作速度非常快,并且在处理数据期间它记录为空字符串,但数据实际上进来了!
  • 在处理数据时,我不断收到导致问题的新数据。有没有办法在处理完成后设置障碍来寻找新数据。

标签: c# c#-4.0 .net-4.0 udp udpclient


【解决方案1】:

您的 UDPListener 和 while 循环的主要区别在于,在循环中,您每次连接到 UDP 时都会创建 udp 变量:

 udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);

Receive(IAsyncResult ar) 中,您只连接同一个客户端,因此您仍然拥有相同的数据。
我认为您可以像这样重写您的课程:

private void StartListening()
{
    udp = new UdpClient(PORT_NUMBER, AddressFamily.InterNetwork);
    ar_ = udp.BeginReceive(Receive, new object());
}

使用Close()方法接收后确保你是disposing the udp connection

byte[] bytes = udp.EndReceive(ar, ref ip);
udp.Close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-06
    相关资源
    最近更新 更多