考虑以下使用Borland 2007和Indy UDP服务器和客户端的最小程序:

struct DATA_PACKAGE
{
    int t;
    int x;
    int y;
};

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   DATA_PACKAGE a;
   a.t = 3;
   a.x = 2;
   a.y = 1;
   Form1->Memo1->Lines->Add("sent " + IntToStr(sizeof(DATA_PACKAGE)));
   Form1->UDPClient1->SendBuffer(server,port,RawToBytes(&a, sizeof(DATA_PACKAGE)));
}

void __fastcall TForm1::UDPServer1UDPRead(TObject *Sender, TBytes AData,
      TIdSocketHandle *ABinding)
{
    DATA_PACKAGE r;
    Form1->Memo1->Lines->Add("received " + IntToStr(sizeof(AData)));
    BytesToRaw(AData, &r, sizeof(AData));
    Form1->Memo1->Lines->Add(IntToStr(r.t) + " " + IntToStr(r.x) + " " + IntToStr(r.y));
}


输出:

sent 12
received 4
3 4717901 0


首先,为什么发送12个字节,却只接收4个字节?

其次,x和y发生了什么?

当我将t,x,y的数据类型更改为short时,我得到:

sent 6
received 4
3 2 0


环顾四周,我发现有指针指出该结构的打包(或可能是字节序?)很重要,但是我找不到清晰的指南来正确设计它。

最佳答案

TBytes是一个动态字节数组,由RTL实现为指针,这就是sizeof(AData)返回4的原因。请勿使用sizeof(AData),而应使用AData.Length属性:

void __fastcall TForm1::UDPServer1UDPRead(TObject *Sender, TBytes AData,
      TIdSocketHandle *ABinding)
{
    DATA_PACKAGE r;
    Form1->Memo1->Lines->Add("received " + IntToStr(AData.Length));
    BytesToRaw(AData, &r, AData.Length);
    Form1->Memo1->Lines->Add(IntToStr(r.t) + " " + IntToStr(r.x) + " " + IntToStr(r.y));
}

10-06 05:20