Indy UDP服务器速度非常低

时间:2018-02-05 11:02:42

标签: sockets c++builder indy

我使用RAD Studio 10.2和Indy 10,一个组件IdUDPServer。 为了测试UDP连接的速度,我安装了程序UDP Test Tool

我检查UDP服务器速度的代码:

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

int readCounter = 0;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Memo1->Clear();
    TIdSocketHandle *SocketHandle = IdUDPServer1->Bindings->Add();
    SocketHandle->IP = "127.0.0.1";
    SocketHandle->Port = 14014;
    IdUDPServer1->Active = true;
    if (IdUDPServer1->Active == true) {
        Memo1->Lines->Add("Сервер стартовал");
        Button1->Enabled = false;
        Button2->Enabled = true;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Memo1->Clear();
    IdUDPServer1->Active = false;
    IdUDPServer1->Bindings->Clear();
    if(IdUDPServer1->Active == false) {
        Memo1->Lines->Add("Сервер остановлен");
        Button1->Enabled = true;
        Button2->Enabled = false;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdUDPServer1UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData,
          TIdSocketHandle *ABinding)
{
    readCounter++;
    Edit1->Text = readCounter;

    char* szBuff = new char[AData.Length];
    memset(szBuff, 0, AData.Length);
    BytesToRaw(AData, szBuff, AData.Length);
    Memo1->Lines->Add(ToHex(AData));
    Memo1->Clear();
    delete szBuff;
}
//---------------------------------------------------------------------------

我在方法readCounter中使用IdUDPServer1UDPRead以便稍后与通过下载的测试实用程序发送的数据包数进行比较,但计数器不匹配。可以看出组件IdUDPServer已经很晚了。

screenshot

可能是什么问题?

1 个答案:

答案 0 :(得分:0)

默认情况下,//new member functions in Simple class auto begin() { std::begin(values); } auto end() { std::end(values); } 属性为TIdUDPServer::ThreadedEvent。这意味着每次服务器收到数据包时,false事件处理程序都会通过OnUDPRead与主UI线程同步同步。当然,这会降低服务器的整体性能。

要使服务器更快地对UDP数据包做出反应,您需要使TThread::Synchronize()事件处理程序更快地将控制权返回到OnUDPRead。这意味着将TIdUDPServer设置为ThreadedEvent以跳过true调用,根本不访问用户界面(或至少使用{异步更新UI {1}}或TThread::Synchronize()),并删除任何会降低处理程序速度的无用代码(您正在分配和填充一个根本没有用于任何内容的TThread::Queue()缓冲区,所以这只是浪费在头顶上。)

例如,如果您使用的是基于Clang的编译器:

TIdNotify

否则,如果您使用的是经典编译器:

char[]

或者:

// make sure ThreadedEvent=true...
void __fastcall TForm1::IdUDPServer1UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData, TIdSocketHandle *ABinding)
{
    ++readCounter;
    TThread::Queue(nullptr,
        [=]() {
            Edit1->Text = readCounter;
            Memo1->Lines->Add(ToHex(AData));
        }
    );
}