Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.02;
Скачать: CL | DM;

Вниз

TStream   Найти похожие ветки 

 
ZDenis ©   (2005-12-21 15:58) [0]

Здравствуйте.Подскажите как правильно сделать.При помощи Indy UDP Server получаю

UDP пакет.Данные в UDP пакете состоят из заголовка flowheader 24 байта

flowheader:record
  version:word;
  count:word;(количество записей в пакете)
  sysuptime:LongWord;
  unix_secs:LongWord;
  unix_nsecs:LongWord;
  flowsequence:LongWord;
  .......
  .......
end;
и записей flowrecord размером 64 байта не более 30.

flowrecord:record
  srcip:LongWord;
  prot:byte;
  dstport:word;
  dpkts:LongWord;
  .......
  .......
end;
Как правильно считать записи из AData:Tstream?


 
Digitman ©   (2005-12-21 16:10) [1]

а собственно UDP-дейтаграмму как таковую (т.е. в виде некоего байт-блока) прочитать не составляет труда ?


 
Eraser ©   (2005-12-21 16:17) [2]


> ZDenis ©   (21.12.05 15:58)

OnUDPRead компонента TIdUDPServer в Indy 10 описан немного по-другому. Советую использовать именно Indy 10.
TUDPReadEvent = procedure(Sender: TObject; AData: TIdBytes; ABinding: TIdSocketHandle) of object;


 
ZDenis ©   (2005-12-21 16:22) [3]

>Digitman ©
На сколько я понимаю считать определенное количество байт можно AData.ReadBuffer или AData.Read.
>Eraser ©
Попробую,но пока у меня  Indy 9


 
Digitman ©   (2005-12-21 16:44) [4]


> ZDenis ©   (21.12.05 16:22) [3]


правильно понимаешь.

и ?

прочитал ?

и что дальше ? и какие проблемы ?


 
ZDenis ©   (2005-12-21 17:19) [5]

Затем мы считываем заголовок
AData.Position :=1;
AData.Readbuffer(flowheader.version,2);
AData.Readbuffer(flowheader.count,2);
.....
затем первую запись.
Вопрос можно ли организовать массив записей,чтобы в них хранить информацию обо всех записях в пакете?


 
Digitman ©   (2005-12-21 18:17) [6]


> Затем мы считываем заголовок


какой нахрен "заголовок" ?!

считывай ВЮ дейтаграмму !

а уж потом пытайся интерпретировать ее логическое содержимое ..

на то она и дейтаграмма. что принимается ЦЕЛИКОМ ...


 
ZDenis ©   (2005-12-22 10:19) [7]

А так нельзя?
type
 Tflowheader=packed record
  version:word;
  count:word;
  sysuptime:LongWord;
  unix_secs:LongWord;
  unix_nsecs:LongWord;
  flow_sequence:LongWord;
  engine_type:byte;
  engine_id:byte;
  sampling_interval:word;
end;
type
 Tflowrecord=packed record
  srcaddr:LongWord;
  dstaddr:longword;
  nexhop:LongWord;
  input:word;
  output:word;
  dPkts:longword;
  dOctets:longword;
  First:longword;
  Last:longword;
  srcport:word;
  dstport:word;
  pad1:byte;
  tcp_flags:byte;
  prot:byte;
  tos:byte;
  src_as:word;
  dst_as:word;
  src_mask:byte;
  dst_mask:byte;
  pad2:word;
 end;
.........
var
 flowheader:TFlowheader;
 flowrecord:TFlowrecord;
begin
 AData.Position :=0;
 AData.Readbuffer(flowheader,24);
 for i:=1 to flowheader.count do  
 AData.Readbuffer(flowrecord,48);


и еще возник вопросик приходят первые два байта так 00000000.00000101,а потом в flowrecord.version они получаются 00000101.000000000 т.е. совсем другое число.


 
Digitman ©   (2005-12-22 10:49) [8]

лучше так:

type

Tflowheader=packed record
 version:word;
 count:word;
 sysuptime:LongWord;
 unix_secs:LongWord;
 unix_nsecs:LongWord;
 flow_sequence:LongWord;
 engine_type:byte;
 engine_id:byte;
 sampling_interval:word;
end;

Tflowrecord=packed record
 srcaddr:LongWord;
 dstaddr:longword;
 nexhop:LongWord;
 input:word;
 output:word;
 dPkts:longword;
 dOctets:longword;
 First:longword;
 Last:longword;
 srcport:word;
 dstport:word;
 pad1:byte;
 tcp_flags:byte;
 prot:byte;
 tos:byte;
 src_as:word;
 dst_as:word;
 src_mask:byte;
 dst_mask:byte;
 pad2:word;
end;

Pflowrecords = ^Tflowrecords;
Tflowrecords = array[0..65535] of Tflowrecord;

.........
var
flowheader:TFlowheader;
flowrecords:PFlowrecords;

...
AData.Position :=0;
AData.Readbuffer(flowheader, sizeof(flowheader));
GetMem(flowrecords, flowheader.count);
for i:= 0 to flowheader.count - 1 do  
 AData.Readbuffer(flowrecords[i]^, sizeof(flowrecord));


> приходят первые два байта так 00000000.00000101,а потом
> в flowrecord.version они получаются 00000101.000000000 т.
> е. совсем другое число


все правильно.
байты в многобайтных переменных хранятся в intel-порядке, т.е. в порядке от младшего к старшему


 
ZDenis ©   (2005-12-22 10:58) [9]

спасибо.
А намекните как сделать,чтобы скажем в flowrecord.version было то число которое пришло?


 
Digitman ©   (2005-12-22 10:59) [10]


> ZDenis ©   (22.12.05 10:58) [9]


да не надо ничего делать !

то которое ты отправил, то самое и пришло


 
ZDenis ©   (2005-12-22 11:06) [11]

отправляю не я,а маршрутизатор.И если я правильно понимаю он отправляет  00000000.00000101 т.е. 5,а как сделать чтобы у меня flowrecord.version было 5?


 
Digitman ©   (2005-12-22 11:24) [12]

значит, маршрутизатор отправляет данные не в хост-порядке, а в сетевом порядке

т.е. после получения тебе нужно поменять байты в поле version местами.

то же самое касается и прочих многобайтных полей - следует "зеркально" поменять в них значения байтов

для значения типа word можно воспользоваться ф-цией BSwap (Byte Swap, кажется, так она называется, уточни в справке)

для смены порядка следования байтов в 4-хбайтных значениях можно воспользоваться ф-цией ntohl() (network to host order) , а для 2-хбайтных - ntohs(), обе ф-ции объявлены в winsock.pas


 
Digitman ©   (2005-12-22 11:25) [13]

впрочем, по поводу других полей - это нужно явно уточнить


 
ZDenis ©   (2005-12-22 11:37) [14]

Вот нашел.
function Swap(X);

Description

In Delphi code, Swap exchanges the high-order bytes with the low-order bytes of the argument. X is an expression of type SmallInt, as a 16-bit value, or Word. This is provided for backward compatibility only.


 
Digitman ©   (2005-12-22 11:40) [15]


> ZDenis ©   (22.12.05 11:37) [14]


удобней все же воспользоваться ntohs и ntohl


 
ZDenis ©   (2005-12-22 12:42) [16]

>Digitman ©
А здесь мы разве правильно память выделяем? GetMem(flowrecords, flowheader.count);
а не так
GetMem(flowrecords,sizeof(flowrecord) flowheader.count)?

и еще  AData.Readbuffer(flowrecords[i]^, sizeof(flowrecord));
пишет Pointer type required


 
ZDenis ©   (2005-12-22 12:44) [17]

GetMem(flowrecords,sizeof(flowrecord)*flowheader.count)


 
Digitman ©   (2005-12-22 12:58) [18]


> ZDenis ©   (22.12.05 12:44) [17]


да, именно так и будет правильно ..


> и еще  AData.Readbuffer(flowrecords[i]^, sizeof(flowrecord));


мог бы и сам сообразить, коль я впопыхах ошибся ...
идея-то должна стать понятной :

Pflowrecord = ^Tflowrecord;
Tflowrecord=packed record
.. тыры-пыры ..
end;

AData.Readbuffer(Pflowrecord(@flowrecords[i])^, sizeof(flowrecord));

p.s.
Паскаль нужно знать и чтить как "Отче наш".



Страницы: 1 вся ветка

Текущий архив: 2006.04.02;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.042 c
2-1142464424
Алекс2
2006-03-16 02:13
2006.04.02
Печать активного документа


3-1139399572
Mishenka
2006-02-08 14:52
2006.04.02
Поля соответствия в таблице связанной сама с собой


2-1142424313
Azeem
2006-03-15 15:05
2006.04.02
Непонятная ошибка


6-1134981691
SergP.
2005-12-19 11:41
2006.04.02
Шифруются ли данные передаваемые на сервер по HTTPS в GET-запросе


15-1141988600
NightLord
2006-03-10 14:03
2006.04.02
Кому нужны вирусы и зачем