【问题标题】:Why do I receive twice the data sent over UDP broadcast?为什么我会收到两倍于通过 UDP 广播发送的数据?
【发布时间】:2010-11-15 00:16:51
【问题描述】:

我对下面的代码有疑问。它的作用是使用 UDP 广播发送当前日期/时间并收听此消息。我目前使用的是本地代码,我在同一台计算机上的同一应用程序中使用发送和接收。我还没有在两台电脑之间尝试过。

public class Agent
{
    public static int Port = 33333;
    public delegate void OnMessageHandler(string message);

    Socket socketSend;
    Socket socketReceive;

    bool receiving = false;
    Thread receiveThread;

    public event OnMessageHandler OnMessage;

    public Agent()
    {
        socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socketSend.EnableBroadcast = true;

        socketSend.Connect(new IPEndPoint(IPAddress.Broadcast, Port));

        socketReceive = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        socketReceive.EnableBroadcast = true;

        socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));
    }

    public void Start()
    {
        Console.WriteLine("Agent started!");

        receiving = true;
        receiveThread = new Thread(new ThreadStart(Receive));
        receiveThread.IsBackground = true;
        receiveThread.Start();
    }

    public void Stop()
    {
        receiving = false;

        socketSend.Close();
        socketReceive.Close();

        receiveThread.Join();

        Console.WriteLine("Agent ended.");
    }

    public void Send(string message)
    {
        Console.WriteLine("Sending : {0}", message);
        byte[] bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(message));
        socketSend.Send(bytes);
        Console.WriteLine("Message sent.");
    }

    protected void Receive()
    {
        Console.WriteLine("Thread started!");
        while (receiving)
        {
            try
            {
                if (socketReceive.Available > 0)
                {
                    byte[] bytes = new byte[socketReceive.Available];

                    Console.WriteLine("Waiting for receive...");

                    int bytesReceived = socketReceive.Receive(bytes, SocketFlags.None);
                    Console.WriteLine("Bytes received : {0}", bytesReceived);

                    string message = Encoding.UTF8.GetString(bytes);
                    Console.WriteLine("Received message : {0}", message);
                    OnMessage(message);
                }
                else
                {
                    Console.Write(".");
                    Thread.Sleep(200);
                }
            }
            catch (SocketException ex)
            {
                if (ex.SocketErrorCode == SocketError.Interrupted)
                {
                    break;
                }
                else
                {
                    throw;
                }
            }
        }
        Console.WriteLine("Thread ended.");
    }
}

我遇到的问题是它发送了一次数据(当我单击一个按钮时),但它收到的数据量是预期的两倍。例如,一个正常的日期/时间是 19 字节长,但第一次可用大于 0,它的值是 38。接下来的 Receive 调用只抓取 19 个字节,循环继续接下来的 19 个字节。这意味着我收到我的消息两次,当然我只想要一次。

输出示例:

Agent started!
Thread started!
..........Sending : 29/07/2009 12:05:04
Message sent.
Waiting for receive...
Bytes received : 19
Received message : 29/07/2009 12:05:04
Waiting for receive...
Bytes received : 19
Received message : 29/07/2009 12:05:04
......Thread ended.
Agent ended.

【问题讨论】:

  • 为什么要睡觉?任何像样的套接字库都将包含一个阻塞读取方法。 (我根本不懂 C#,但我认为有一个 socketReceive.read() 或类似的方法。)

标签: c# udp broadcast


【解决方案1】:

我建议您先在指定的目标 IP 上尝试此操作。这样一来,网络拓扑的影响会更小,当一切按您预期的方式运行时,您只需将其移动到广播地址即可。

【讨论】:

    【解决方案2】:
    socketReceive.Bind(new IPEndPoint(IPAddress.Any, Port));
    

    通过绑定到您的所有 IP 地址,您将获得本地环回以及通过网络。

    【讨论】:

    • 非常感谢,我获得了第一个接口的本地IP地址,它工作并用于socketReceive。
    猜你喜欢
    • 1970-01-01
    • 2020-02-21
    • 2021-12-18
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 2011-10-08
    相关资源
    最近更新 更多