На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> socket, парсить пакет
    всем привет!
    пытаюсь научиться адекватно парсить пакеты, нужно что-то на подобии этого чтобы получилось
    user posted image

    ExpandedWrap disabled
      MyType = packed record
      UID: Dword;
      NickLen: byte;
      Nick: String;
      Other: Byte;
      end;
      PMyType = ^MyType;
       
      .....................................
       
      var
      t : PMyType;
      buf : TByteArray;
      begin
      buf:=''; //тут данные
      t := PMyType(@buf[0]);
      len:=t^.NickLen;
      SetString ( nick ,pchar(@t.Nick),len);


    Nick - имеет разную длину, она в переменной LEN
    выше способ все парсит но когда я получаю "Other" то он выдает байт не после строки как мне нужно, а выдает 4-ый байт с начала строки =(

    подскажите как мне правильно парсить пакеты, в идеале надо как на скриншоте чтоб вышло
      Так объявлять структуру данных для приема пакета (а также для чтения из файла или записи) нельзя, т.к. string - динамический тип - указатель на данные. (В частности, поэтому 4-й байт выдается - размер указателя).
      Так что приведение PMyType(@buf[0]) здесь не к месту.
      Поскольку смещение полей непостоянно, придется использовать, например, PByteArray(@buf[0]), и отдельные поля по текущим смещениям вычленять.
        +1 к MBo

        Держи две полезняшки, пригодятся
        ExpandedWrap disabled
          // Чтение данных из буфера. Копирует ByteCount байт из Src в Dest и передвигает Src
          procedure ReadBytes(var Src: PByte; var Dest; ByteCount: Integer);
          begin
            Move(Src^, Dest, ByteCount);
            Inc(Src, ByteCount);
          end;
           
          // Запись данных в буфер. Копирует ByteCount байт из Src в Dest и передвигает Dest
          procedure WriteBytes(const Src; var Dest: PByte; ByteCount: Integer);
          begin
            Move(Src, Dest^, ByteCount);
            Inc(Dest, ByteCount);
          end;


        Юзать:
        PBuf := @Buf[0];
        ReadBytes(Msg.Type, SizeOf(Msg.Type));
        ReadBytes(Msg.Unk, SizeOf(Msg.Unk));
        ReadBytes(Msg.UID, SizeOf(Msg.UID));
        ...

        Со строками так не получится, читай про них в хелпе
          спасибо за ответ!

          Цитата

          Юзать:
          PBuf := @Buf[0];
          ReadBytes(Msg.Type, SizeOf(Msg.Type));
          ReadBytes(Msg.Unk, SizeOf(Msg.Unk));
          ReadBytes(Msg.UID, SizeOf(Msg.UID));
          ...

          Со строками так не получится, читай про них в хелпе


          тоесть тоже не подходит для строк ил это комментарий к первому посту??

          я так понял тут PBuf : PByteArray;
          но как его юзать все же не понял так как там уже msg.type
          ReadBytes(Msg.Type, SizeOf(Msg.Type));
            Ну я брал за основу таблицу, которую ты выложил.
            Строки надо будет сначала сделать нужной длины, а потом считывать в адрес первого символа. Причем еще учесть, что строки д.б. однобайтовые (для Delphi 2009+ - AnsiString)

            Добавлено
            Цитата AHTOLLlKA @
            я так понял тут PBuf : PByteArray;

            PBuf - это просто указатель на буфер байт, имеет тип PByte.
              ExpandedWrap disabled
                PBuf := @Buf[0];
                 ReadBytes(Msg.Type, SizeOf(Msg.Type));


              не могу понять, если данные в PBuF то как их передать в ReadBytes ? =(
              ни разу не встречался с
              ExpandedWrap disabled
                var Src: PByte; var Dest;


              смысл понимаю но как правильно сделать не догоняю, подскажите :yes-sad:

              Добавлено
              ExpandedWrap disabled
                PBuf,dd: PByte;
                begin
                 
                buf:=AnsiStringToByteArray(('01000049B6930C1B042E04110440004200400022041E0421041A04'));
                PBuf := @buf[0];            
                 
                ReadBytes(PBuf , dd, 12);
                 
                memo2.lines.add(pchar(@dd));


              вернул - 0100:049B6™
              и вывалилась ошибка, почему так?(
                >и вывалилась ошибка, почему так?(
                Потому что под содержимое dd не выделена память
                  ExpandedWrap disabled
                    function AnsiStringToByteArray(aString : AnsiString) : TByteArray;
                     var
                     len : integer;
                     begin
                     len := Length(aString);
                     if len > 0 then begin
                     SetLength(result, len);
                     MoveMemory(@result[0], @aString[1], len);
                     end;
                     end;


                  выделяет память, можете поделиться простым кодом чтобы скопировать байты из одного TByteArray в другой TByteArray с длиной и в первоночальном TByteArray удалить их (то что скопировано)
                  :'(
                    функция AnsiStringToByteArray практически бессмысленная. Копировать байты из одного TByteArray в другой, да еще удалять -тоже странное.
                    Лучше вернуться к реальной задаче. Нужно заполнить структуру MyType? Исходные данные где хранятся?
                      данные хранятся в TByteArray
                      нужно из src в которой - 01 02 03 04 05
                      в dest положить 01 02 (первые например два байта)
                      и из src удалить эти первые два байта чтобы он стал - 03 04 05
                      вот

                      делаю так

                      Код:
                      ExpandedWrap disabled
                        var
                        src,dest: TByteArray;
                        setlength(dest,6);
                        MoveMemory( @dest[0], @src[0], 6);


                      все отлично, но как удалить через INC не понимаю (
                        ExpandedWrap disabled
                          var
                          src,dest: TByteArray;
                          srcindex, destindex: Integer;
                          begin
                            setlength(dest,6);
                            srcindex := 0;
                            destindex := 0;
                            Move(src[srcindex], dest[destindex], 2);
                            Inc(srcindex, 2); //сместили индекс источника, теперь можно продолжать копировать с нового места
                        Сообщение отредактировано: MBo -
                          ExpandedWrap disabled
                             Inc(srcindex, 2); //сместили индекс источника, теперь можно продолжать копировать с нового места


                          тут что то не так)
                          Inc(src[srcindex], 2);
                          если так то он меняет этот символ на +2 =(
                            разницы не видишь между тем, что у меня, и у тебя написано?
                              ExpandedWrap disabled
                                var
                                src,dest: TByteArray;
                                srcindex, destindex: Integer;
                                begin
                                src:=AnsiStringToByteArray(HexToString('01000049B6930C1B042E04110440004200400022041E0421041A04'));
                                  setlength(dest,4);
                                  srcindex := 0;
                                  destindex := 0;
                                  Move(src[srcindex], dest[destindex], 4);
                                  Inc(srcindex, 2); //сместили индекс источника, теперь можно продолжать копировать с нового места
                                 
                                memo2.lines.add(String2Hex(ByteArrayToAnsiString(dest)));
                                memo2.lines.add(String2Hex(ByteArrayToAnsiString(src)));


                              на выходе
                              01000049
                              01000049b6930c1b042e04110440004200400022041e0421041a04
                                Скопировали 4 байта, они в приемнике.
                                Раз 4 байта копировали, то и Inc индекса нужно на 4 делать.
                                Новый srcindex будет указывать на байт b6

                                Если вопрос в удалении - так оно не нужно.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.0829 ]   [ 15 queries used ]   [ Generated: 24.10.26, 05:48 GMT ]