首页 > 解决方案 > C ++中的UDP帧丢失

问题描述

我有一个 C# 代码,它从 UDP 获取数据并计算丢失的帧(如果有)。它工作正常。我用 C++ 编写了相同的代码,看看我是否比 C# 代码更快地获取数据。

但是,在进行比较之前,我遇到了问题;在 C++ 代码中,我丢失了很多帧。

在这两个代码中;我将部分数据解析为用户创建的标题。一帧由 7 个片段组成。FrameFragmentNo按顺序计算段。在 C# 代码中它计数为 1,2,3..7 但在 C++ 中它从 5 等开始并计数为 5,6 然后新帧出现 1,6 等。这意味着 C++ 代码永远不会正确地获取帧。(C# 代码丢失框架自然但很少见)TotalFragmentCount对两者都是正确的。

safe_increment是在计算框架的碎片时,在顺序被破坏时计算一次。不要介意intData这是关于其余数据的一些过程。

有趣的是,当我跟踪 C++ 代码时,有时它的计数是正确的。我怀疑 Windows 操作系统的缓冲区大小,但如果是这种情况,C# 代码应该不能正常工作。我检查了其他帖子,大多数人问包裹丢失,但是我有一个框架丢失。我还想,也许我拍帧太快了,但它无法提出解决方案。

有人对这种行为有什么建议吗?

这是 C# 代码工作正常,按顺序计算帧片段

private void ReceiveData()
    {

        byte[] content;
        UInt16[] intData = new UInt16[0] { };
        UInt16 SkipFrameFlag = 1;


        dataReceiveThreadStarted = true;

        while (true)
        {
            content = udpClientData.Receive(ref IPEndPointDataReceiveInformation);//C# skips UDP header
            if (!DataReceiveEnabled)
            {
                continue;
            }

            //-------------------Parse User Created Header---------------------------
            MessageID = (UInt16)(content[0] << 8 | content[1]);
            FrameCount = (UInt32)(content[2] << 24 | content[3] << 16 | content[4] << 8 | content[5] << 0);
            TotalFragmentCount = (UInt16)(content[6] << 8 | content[7]);
            FrameFragmentNo = (UInt16)(content[8] << 8 | content[9]);
            Reserved = (UInt16)(content[10] << 8 | content[11]);
            MessageLength = (UInt16)(content[12] << 8 | content[13]);


            if (FrameFragmentNo == 1 && SkipFrameFlag == 1)  // After the skip flag, catch the start of frame.
            {

                SkipFrameFlag = 0;
                PrevFrameFragmentNo = 0;
                safe_increment = true;
                Array.Clear(intData, 0, intData.Length);
            }
            //Fragment is lost. Skip Frame
            if (FrameFragmentNo != (PrevFrameFragmentNo + 1)) {
                SkipFrameFlag = 1;

                //increment once when a frame is lost
                if (safe_increment)
                {
                    lostFrameCount++;
                    safe_increment = false;
                }
            } 


            if (SkipFrameFlag == 1)
                continue;

            if (FrameFragmentNo == TotalFragmentCount && intData != null) // Frame Fragmentation Completed
            {
                ragmentNo = 0;
                PrevFrameCount = FrameCount;
                ReceivedFrameCount++;
                ReceivedFrameLen = intData.Length;
        }
    }

这是丢失太多帧或花费太快的 C++ 代码我不知道

while (true)
{
    ZeroMemory(&client, clientLength); // Clear the client structure
    ZeroMemory(buf, 1550); // Clear the receive buffer

    // Wait for message
    int bytesIn = recvfrom(in, buf, 1550, 0, (sockaddr*)&client, &clientLength);

    if (bytesIn == SOCKET_ERROR)
    {
        cout << "Error receiving from client " << WSAGetLastError() << endl;
        continue;
    }


    //-------------------Parse User Created Header----------------------
    MessageID = (uint16_t)(buf[0] << 8 | buf[1]);
    FrameCount = (uint32_t)(buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5] << 0);
    TotalFragmentCount = (uint16_t)(buf[6] << 8 | buf[7]);
    FrameFragmentNo = (uint16_t)(buf[8] << 8 | buf[9]);
    Reserved = (uint16_t)(buf[10] << 8 | buf[11]);
    MessageLength = (uint16_t)(buf[12] << 8 | buf[13]);


    if (FrameFragmentNo == 1 && SkipFrameFlag == 1)  // After the skip flag, catch the start of frame.
    {
        SkipFrameFlag = 0;
        PrevFrameFragmentNo = 0;
        safe_increment = true;
        intData.clear();

    }

    if (FrameFragmentNo != (PrevFrameFragmentNo + 1)) //Fragment is lost. Skip Frame
    {
        SkipFrameFlag = 1;
        if (safe_increment) {
            lostFrameCount++;
            safe_increment = false;
        }

    }


    if (SkipFrameFlag == 1)
        continue;



if (FrameFragmentNo == TotalFragmentCount && intData.size() != 0) // Frame Fragmentation Completed
    {
        PrevFrameFragmentNo = 0;
        PrevFrameCount = FrameCount;
        ReceivedFrameCount++;
        ReceivedFrameLen = intData.size();

    }
 }

标签: c#c++serverudp

解决方案


推荐阅读