Текущий архив: 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.49 MB
Время: 0.076 c