【问题标题】:Delphi - Why udp data packet is different?Delphi - 为什么udp数据包不同?
【发布时间】:2016-06-01 05:58:56
【问题描述】:

我想了解为什么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

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

这里是network sniffer Wireshark的日志

我也尝试过使用 TIDUDPClient,但问题是一样的。

感谢所有帮助。

【问题讨论】:

  • 在填充buffer 之前bufferS 的值是多少?您确定您实际上在调试器中查看正确的buffer(查看代码时代码在哪一行停止?),并且在 Wireshark 中查看正确的数据包?我怀疑你在看两种不同的东西。 Indy 不会更改正在发送的数据。
  • 如何在 Indy 版本中声明 SendBuffer?它是使用 TIdBytes 参数还是无类型 var 参数?
  • @MBo:给定显示的代码,它必须是 var 版本(Indy 9),因为 TIdBytes 版本(Indy 10)没有明确的长度参数,它使用而是数组的长度。
  • @Remy Lebeau 好吧,所以我建议作者发送指针而不是数组主体。
  • @MBo:是的,这就是必须发生的事情。

标签: delphi udp delphi-7 indy indy-9


【解决方案1】:

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

procedure SendBuffer(AHost: string; const APort: Integer; var ABuffer; const AByteCount: integer);

注意ABuffer 是一个无类型的var。这意味着您可以将 anything 传递给它,它会接收您传入的任何变量的内存地址。

您的buffer 被声明为动态数组(可能是由于您使用了SetLength())。动态数组在内部实现为指向位于内存中其他位置的内存块的指针。当您将动态数组变量传递给无类型的var 参数时,该参数接收到变量本身的内存地址,而不是变量指向的数组数据的内存地址。这就是为什么您会看到在套接字上发送“垃圾” - 您实际上是在发送数据指针本身的字节!您的代码发生不会崩溃,因为您的 buffer 长度为 4,而 Delphi 7 中的指针大小为 4 个字节。

为了让var 参数接收实际数组数据的内存地址,您必须:

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

    TIdUDPServer(item).SendBuffer(..., buffer[0], Length(buffer));
    
  2. 将数组变量类型转换为适当的指针类型(在这种情况下,可能bufferarray of Byte,所以使用PByte)然后取消引用指针:

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

【讨论】:

    猜你喜欢
    • 2012-05-05
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 2017-04-04
    相关资源
    最近更新 更多