2016-02-19 17 views
0

我想明白为什么在Wireshark程序中收到的数据包与我的delphi应用程序发送的数据包不同。谁能帮我?德尔福 - 为什么udp数据包不同?

这里是我的代码:

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 

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

Buffer

这里日志的network sniffer Wireshark

Wireshark

我我试过无线TIDUDPClient也是如此,但问题是一样的。

感谢您的帮助。

+0

在填充'buffer'之前'bufferS'的值是什么?你确定你实际上是在调试器中查看正确的'buffer'(以及在查看它时哪些代码停止了?),并且在Wireshark的正确数据包中?我怀疑你正在看两件不同的事情。 Indy不会更改正在发送的数据。 –

+0

如何在您的Indy版本中声明SendBuffer?它使用TIdBytes参数还是使用无类型的var参数? – MBo

+0

@MBo:给出显示的代码,它必须是'var'版本(Indy 9),因为'TIdBytes'版本(Indy 10)没有明确的长度参数,所以它使用数组长度代替。 –

回答

4

在印9,SendBuffer()声明如下:

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

注意,ABuffer是一个无类型var。这意味着你可以通过任何它,它收到你传进去的变量的内存地址。

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));