【问题标题】:UDP client only receives a message and freezesUDP客户端只收到一条消息并冻结
【发布时间】:2015-09-14 17:42:10
【问题描述】:

UDP 客户端只收到一条消息并冻结

定时器只运行一次,不知道如何跟随他来clinte UDP消息来

namespace temp {
    public partial class Form1 : Form
    {  

    }
    public Form1()
    {
        InitializeComponent();    
    }
    private void Form1_Load(object sender, EventArgs e)
    { 

    }
    private void label1_Click(object sender, EventArgs e)
    {

    }
}

只运行一次

private void timer1_Tick(object sender, EventArgs e) {
    UdpClient client = new UdpClient();
    IPEndPoint localEp = new IPEndPoint(IPAddress.Any, 22);
    client.Client.SetSocketOption(SocketOptionLevel.Socket,           SocketOptionName.ReuseAddress, true);
    client.Client.Bind(localEp);
    IPAddress multicastaddress = IPAddress.Parse("127.0.0.1");
    Byte[] data = client.Receive(ref localEp);
    string mensaje = Encoding.UTF8.GetString(data);
    label1.Text += "" + mensaje.ToString() + "";
}

【问题讨论】:

  • 这段代码不是每个时钟滴答都会打开一个新客户端而不关闭任何客户端吗?
  • 是真的收到消息还是卡在同步接收消息上?
  • @WDS 他说计时器只运行一次,如果那不是真的,当他试图在同一个端口上绑定两个套接字时,他会得到一个异常,无论如何都会阻止他。
  • 为什么要使用定时器从套接字同步接收数据?为什么你在为 SSH 保留的端口上监听,同时期待 UTF-8 文本?此外,ReuseAddress 并没有按照您的想法执行 - 这只是意味着您在绑定到同一个地址两次时不会出错;这并不意味着所有的听众都会收到消息。这显然是您尝试过的事情,因为您没有干净地处理您的客户。请不要只是猜测网络的方式——这是一个非常复杂的主题,而且很容易出错。先了解你在做什么。

标签: c# timer


【解决方案1】:

Windows 在 UI 线程上形成计时器“滴答声”。这意味着在您花费在timer_tick 处理程序中的时间里,UI 不会刷新,并且您的应用程序看起来会被冻结。

client.Receive() 方法默认是一个阻塞操作,这意味着它会等待直到有消息可用。

您需要在此处更改一些内容:

  • UdpClient的创建移到timer_tick函数之外;整个应用程序只需要一个实例
  • 删除SocketOption.ReuseAddress,因为您将不再需要它
  • 使用异步方法而不是阻塞client.Receive(),因此您甚至不再需要计时器。
  • 如果你对异步编程的任务感到手忙脚乱,你可以设置client.Client.Blocking = false并捕捉到对应的SocketException。但是,对常规控制流使用异常是不好的。

【讨论】:

  • 他根本不应该在这里使用任何计时器。 APM 模式也已过时。使用等待。
  • @usr 同意,稍微更新了答案。我还没有开始使用更新的框架,所以我保持这个方向有点模糊。应该有很多例子,比如stackoverflow.com/a/24154685/292411
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-18
  • 1970-01-01
  • 2020-01-10
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多