![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TStream [D7]
ZDenis © (2005-12-21 15:58:00)Здравствуйте.Подскажите как правильно сделать.При помощи 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-22 12:58:00) [1]
> 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.
Паскаль нужно знать и чтить как "Отче наш".
ZDenis (2005-12-22 12:44:00) [2]GetMem(flowrecords,sizeof(flowrecord)*flowheader.count)
ZDenis (2005-12-22 12:42:00) [3]>Digitman ©
А здесь мы разве правильно память выделяем? GetMem(flowrecords, flowheader.count);
а не так
GetMem(flowrecords,sizeof(flowrecord) flowheader.count)?
и еще AData.Readbuffer(flowrecords[i]^, sizeof(flowrecord));
пишет Pointer type required
Digitman (2005-12-22 11:40:00) [4]
> ZDenis © (22.12.05 11:37) [14]
удобней все же воспользоваться ntohs и ntohl
ZDenis (2005-12-22 11:37:00) [5]Вот нашел.
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:25:00) [6]впрочем, по поводу других полей - это нужно явно уточнить
Digitman (2005-12-22 11:24:00) [7]значит, маршрутизатор отправляет данные не в хост-порядке, а в сетевом порядке
т.е. после получения тебе нужно поменять байты в поле version местами.
то же самое касается и прочих многобайтных полей - следует "зеркально" поменять в них значения байтов
для значения типа word можно воспользоваться ф-цией BSwap (Byte Swap, кажется, так она называется, уточни в справке)
для смены порядка следования байтов в 4-хбайтных значениях можно воспользоваться ф-цией ntohl() (network to host order) , а для 2-хбайтных - ntohs(), обе ф-ции объявлены в winsock.pas
ZDenis (2005-12-22 11:06:00) [8]отправляю не я,а маршрутизатор.И если я правильно понимаю он отправляет 00000000.00000101 т.е. 5,а как сделать чтобы у меня flowrecord.version было 5?
Digitman (2005-12-22 10:59:00) [9]
> ZDenis © (22.12.05 10:58) [9]
да не надо ничего делать !
то которое ты отправил, то самое и пришло
ZDenis (2005-12-22 10:58:00) [10]спасибо.
А намекните как сделать,чтобы скажем в flowrecord.version было то число которое пришло?
Digitman (2005-12-22 10:49:00) [11]лучше так:
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:19:00) [12]А так нельзя?
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-21 18:17:00) [13]
> Затем мы считываем заголовок
какой нахрен "заголовок" ?!
считывай ВЮ дейтаграмму !
а уж потом пытайся интерпретировать ее логическое содержимое ..
на то она и дейтаграмма. что принимается ЦЕЛИКОМ ...
ZDenis (2005-12-21 17:19:00) [14]Затем мы считываем заголовок
AData.Position :=1;
AData.Readbuffer(flowheader.version,2);
AData.Readbuffer(flowheader.count,2);
.....
затем первую запись.
Вопрос можно ли организовать массив записей,чтобы в них хранить информацию обо всех записях в пакете?
Digitman (2005-12-21 16:44:00) [15]
> ZDenis © (21.12.05 16:22) [3]
правильно понимаешь.
и ?
прочитал ?
и что дальше ? и какие проблемы ?
ZDenis (2005-12-21 16:22:00) [16]>Digitman ©
На сколько я понимаю считать определенное количество байт можно AData.ReadBuffer или AData.Read.
>Eraser ©
Попробую,но пока у меня Indy 9
Eraser (2005-12-21 16:17:00) [17]
> ZDenis © (21.12.05 15:58)
OnUDPRead компонента TIdUDPServer в Indy 10 описан немного по-другому. Советую использовать именно Indy 10.
TUDPReadEvent = procedure(Sender: TObject; AData: TIdBytes; ABinding: TIdSocketHandle) of object;
Digitman (2005-12-21 16:10:00) [18]а собственно UDP-дейтаграмму как таковую (т.е. в виде некоего байт-блока) прочитать не составляет труда ?