Delphi-为什么udp数据包不同?

Delphi-为什么udp数据包不同?,delphi,udp,delphi-7,indy,indy-9,Delphi,Udp,Delphi 7,Indy,Indy 9,我想了解为什么在Wireshark程序中接收的数据包与我的delphi应用程序发送的数据包不同。有人能帮我吗 这是我的密码: if Pos('\x',comandoRede.Comando) > 0 then begin bufferS := Explode('\x',comandoRede.Comando); SetLength(buffer,Length(bufferS)-1); for J := 0 to Length(Buffer) -1 do begin

我想了解为什么在
Wireshark
程序中接收的数据包与我的delphi应用程序发送的数据包不同。有人能帮我吗

这是我的密码:

if Pos('\x',comandoRede.Comando) > 0 then
begin

  bufferS := Explode('\x',comandoRede.Comando);

  SetLength(buffer,Length(bufferS)-1);

  for J := 0 to Length(Buffer) -1 do
  begin

    buffer[J] := StrToInt('$'+bufferS[J+1]);

  end;

    TIdUDPServer(item).SendBuffer(equipamentoRede.IP,
      StrToInt(equipamentoRede.Port),buffer,Length(buffer));

end
这里是缓冲区数组的内容:

这里是网络嗅探器Wireshark的日志

我也尝试过使用TIDUDPClient,但问题是相同的


谢谢你的帮助

在Indy 9中,
SendBuffer()
声明如下:

procedure SendBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
请注意,
ABuffer
是一个非类型化的
var
。这意味着您可以向它传递任何内容,它将接收您传入的任何变量的内存地址

您的
缓冲区
被声明为动态数组(可能是由于您使用了
SetLength()
)。动态数组在内部实现为指向驻留在内存中其他位置的内存块的指针。将动态数组变量传递给非类型化的
var
参数时,该参数将接收变量本身的内存地址,而不是变量所指向的数组数据的内存地址。这就是为什么在套接字上发送“垃圾”——实际上是在发送数据指针本身的字节!您的代码碰巧没有崩溃,因为您的
缓冲区长度为4,而Delphi7中的指针大小为4字节

要使
var
参数接收实际阵列数据的内存地址,必须:

  • 索引到数组的第一个元素:

    TIdUDPServer(item).SendBuffer(..., buffer[0], Length(buffer));
    
  • type将数组变量强制转换为适当的指针类型(在这种情况下,假定
    缓冲区
    是一个
    字节数组
    ,因此使用
    PByte
    ),然后取消引用指针:

    TIdUDPServer(item).SendBuffer(..., PByte(buffer)^, Length(buffer));
    

  • 在Indy 9中,
    SendBuffer()
    声明如下:

    procedure SendBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);
    
    请注意,
    ABuffer
    是一个非类型化的
    var
    。这意味着您可以向它传递任何内容,它将接收您传入的任何变量的内存地址

    您的
    缓冲区
    被声明为动态数组(可能是由于您使用了
    SetLength()
    )。动态数组在内部实现为指向驻留在内存中其他位置的内存块的指针。将动态数组变量传递给非类型化的
    var
    参数时,该参数将接收变量本身的内存地址,而不是变量所指向的数组数据的内存地址。这就是为什么在套接字上发送“垃圾”——实际上是在发送数据指针本身的字节!您的代码碰巧没有崩溃,因为您的
    缓冲区长度为4,而Delphi7中的指针大小为4字节

    要使
    var
    参数接收实际阵列数据的内存地址,必须:

  • 索引到数组的第一个元素:

    TIdUDPServer(item).SendBuffer(..., buffer[0], Length(buffer));
    
  • type将数组变量强制转换为适当的指针类型(在这种情况下,假定
    缓冲区
    是一个
    字节数组
    ,因此使用
    PByte
    ),然后取消引用指针:

    TIdUDPServer(item).SendBuffer(..., PByte(buffer)^, Length(buffer));
    

  • 在填充
    缓冲区
    之前,
    缓冲区
    的值是多少?是否确实在调试器中查看了正确的
    缓冲区
    (查看时代码停在哪一行?)以及Wireshark中的正确数据包?我怀疑你在看两件不同的事情。Indy不会更改正在发送的数据。在Indy版本中如何声明SendBuffer?它使用TIdBytes参数还是typeless var参数?@MBo:给定所示的代码,它必须是
    var
    版本(Indy 9),因为
    TIdBytes
    版本(Indy 10)没有显式的长度参数,它使用数组的长度来代替。@Remy Lebeau,所以我建议作者发送指针而不是数组体。@MBo:是的,这就是必须发生的事情。
    bufferS
    在填充
    buffer
    之前的值是多少?是否确实在调试器中查看了正确的
    缓冲区
    (查看时代码停在哪一行?)以及Wireshark中的正确数据包?我怀疑你在看两件不同的事情。Indy不会更改正在发送的数据。在Indy版本中如何声明SendBuffer?它使用TIdBytes参数还是typeless var参数?@MBo:给定所示的代码,它必须是
    var
    版本(Indy 9),因为
    TIdBytes
    版本(Indy 10)没有显式的长度参数,它使用数组的长度来代替。@Remy Lebeau,所以我建议作者发送指针而不是数组体。@MBo:是的,这就是必须发生的事情。