Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.04.02;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.039 c
1-1141135536
Kacnep
2006-02-28 17:05
2006.04.02
Отследить запуск DLL


9-1127210142
Signate
2005-09-20 13:55
2006.04.02
Рисование массивами - текстурные координаты


4-1136963799
ver2all
2006-01-11 10:16
2006.04.02
Хочу знать все о HDD


2-1142934011
Nsk3D
2006-03-21 12:40
2006.04.02
Изменение шрифта


5-1128496274
MegaVolt
2005-10-05 11:11
2006.04.02
Множество компонентов в одном контейнере. Как делать?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский