2016-02-19 18 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));