C# 在C语言中接收最新的UDP数据包

C# 在C语言中接收最新的UDP数据包,c#,udp,unity3d,simulink,C#,Udp,Unity3d,Simulink,我使用Unity来可视化一个模拟,其中来自模拟的数据通过来自Simulink的UDP数据包发送给它。我遇到的问题源于Simulink发送UDP数据包的速率以及Unity中的脚本尝试从UDP客户端接收数据的速率 对于我的Unity脚本,我创建了一个线程,该线程执行一个带有while循环的简单函数,并且休眠的时间与客户端超时所需的时间相同,超时时间由我任意设置: public void Start() { // Setup listener. this.mSenderAddress

我使用Unity来可视化一个模拟,其中来自模拟的数据通过来自Simulink的UDP数据包发送给它。我遇到的问题源于Simulink发送UDP数据包的速率以及Unity中的脚本尝试从UDP客户端接收数据的速率

对于我的Unity脚本,我创建了一个线程,该线程执行一个带有while循环的简单函数,并且休眠的时间与客户端超时所需的时间相同,超时时间由我任意设置:

public void Start() {
    //  Setup listener.
    this.mSenderAddress = IPAddress.Parse("127.0.0.1");
    this.mSender = new IPEndPoint(this.mSenderAddress, 30001);

    //  Setup background UDP listener thread.
    this.mReceiveThread = new Thread(new ThreadStart(ReceiveData));
    this.mReceiveThread.IsBackground = true;
    this.mReceiveThread.Start();
}

//  Function to receive UDP data.
private void ReceiveData() {
    try {
        //  Setup UDP client.
        this.mClient = new UdpClient(30001);
        this.mClient.Client.ReceiveTimeout = 250;

        //  While thread is still alive.
        while(Thread.CurrentThread.IsAlive) {
            try {
                //  Grab the data.
                byte[] data = this.mClient.Receive(ref this.mSender);

                //  Convert the data from bytes to doubles.
                double[] convertedData = new double[data.Length / 8];
                for(int ii = 0; ii < convertedData.Length; ii++)
                    convertedData[ii] = BitConverter.ToDouble(data, 8 * ii);

                //  DO WHATEVER WITH THE DATA

                //  Sleep the thread.
                Thread.Sleep(this.mClient.Client.ReceiveTimeout);
            } catch(SocketException e) {
                continue;
            }
        }
    } catch(Exception e) {
        Debug.Log(e.ToString());
    }
}
这里,如果超时/睡眠时间大于Simulink发送UDP数据包的时间差,我的可视化将落后于模拟,因为它将读取发送的下一个数据包,而不是最后一个发送的数据包。它将数据包视为一个队列

是否存在只从接收到的最后一个数据包中获取数据的方法?我知道至少有一种方法可以解决这个问题,因为如果我将速率传输块设置为与UdpClient超时相同或更大的采样时间,它就会工作;但我想让它更健壮


由于我的数据包包含有关模拟位置、方向、时间等状态的完整信息。。。如果我从不使用中间数据包中的数据,这并不重要;只要我得到最新的数据,这将是来自最后一个数据包。

UDP是不可靠的,并且数据包不能保证以相同的发送顺序接收。我的建议是使用TCP或在数据包头中放入某种序列号,继续读取UDP数据包,只选择最新的数据包

我不明白你为什么要暂停。为什么不接收Simulink发送的所有数据,直到发送方超时?接收函数获取整个数据流,而不仅仅是单个或几个数据包。但是,由于整个接收的潜在大小可能非常大,因此每个接收调用只获取由缓冲区大小定义的有限数量的数据。因此,您必须继续调用receive函数,直到缓冲区中剩余的数据为零。在这两者之间不需要休眠或超时,因为这显然会在程序休眠期间在缓冲区中造成溢出。在这种情况下,超过缓冲区大小的数据包将被忽略或丢失;如果不检查套接字中发生了什么类型的异常,那么一旦工作完成,您就必须格外小心中止此线程。否则,可能会导致CPU计数器出现峰值!远远超过你。我的OnApplicationQuit方法已经非常小心地处理了线程