Главная страница
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.044 c
15-1141641390
Некто
2006-03-06 13:36
2006.04.02
Когда-то здесь было сообщение про crossover и FreeBSD


2-1142744184
Фаст
2006-03-19 07:56
2006.04.02
НЕ плавная прокрутка в ListBox. Как её сделать?


2-1142416078
Amina
2006-03-15 12:47
2006.04.02
F1Book помогите!!!


11-1124198675
I_need_Help
2005-08-16 17:24
2006.04.02
Установка МСК


2-1142642475
antonioxxx
2006-03-18 03:41
2006.04.02
Связь расширения с программой. Корректная передача пути файла.