[AD]
[AD]

КомпьюТоп - каталог компьютерных сайтов





































































 
    проект nICQ (урок №3) Шутка...
Назад Содержание Дальше
Урок №3
Запрос информации о клиенте,
Поиск клиентов по различным критериям и др.


Итак... Передавать и принимать сообщения уже умеем. На очереди - получение информации о клиентах, которые находятся в списке контактов; а также поиск новых клиентов по различным критериям. Такие запросы к серверу посылаются с помощью все тех же SNAC(15,2). Вспомните, как производится запрос оффлайновых сообщений.

Точно также SNAC(15,2) с типом запроса равным D007 применяется:

  • при всех операциях с Инфо клиентов ( и получение, и обновление своего);

  • при поиске клиентов по имени, по UINу, по E-mailу;

  • при изменении пароля;

  • при удалении UINа из реестра ICQ;

  • при многих других операциях.


  • Каждая из перечисленных операций определяется подтипом запроса. Приведу обобщенную таблицу SNAC(15,2) для некоторых запросов:

    FLAP
    Command Start 2A
    Channel ID 02
    Sequence Number XX XX
    Data Field Length XX XX

    SNAC (15, 02)
    Family ID 00 15
    SubType ID 00 02
    Flags[0] 00
    Flags[1] 00
    Request ID 00 XX 00 02 (по ним можно опознать ответ)

    TLV (1)
    Type 00 01
    Length XX XX
    Value Length-2
    (и что оно тут делает ?)
    XX XX XX XX наш UIN
    D0 07 тип запроса
    XX 00 cookie
    (по нему можно/нужно
    опознавать ответ)
    B2 04 подтип запроса
    (B204 - запрос инфо клиента)

    Это переменная часть зпроса.
    Она определяется подтипом запроса.

    Например:

    При запросе инфо клиента (B2 04) или при поиске клиента по UINу (1F05) здесь следует разместить запрашиваемый UIN.

    При поиске клиента по E-mail (2905) здесь будет помещена строка с искомым адресом.

    При поиске по NickName, FirstName, LastName (1505) сюда помещаются соответственно три стоки.

    При смене пароля (2E04) здесь будет лишь строка с паролем, а наш UIN сервер и так знает.





    Теперь к Delphi-проекту добавлены еще два модуля: UInfo и SUser (User Info & Search User).
    Очередные исходники <Lesson3.zip> здесь. Т.к. все рассмотренные више запросы практически однотипные, то приведу комментарии только к одному из них. Это будет поиск по NickName, FirstName, LastName:

     unit  SUser;
    procedure TSearchUser.META_Search_User(NN,FN,LN : string);
    var p : PPack;
        // промежуточный массив. 
        // в нем накапливаются данные TLV(1)
        b : TByteArray;
        i : integer;
    begin
         if (NN='')and(FN='')and(LN='') then exit;
         EndOfSearch := false;
    
         // word(b[0]) - тут будет ненужная длина
         // (но ее надо потом корректно заполнить) 
         i:=2;  // а пока переходим к 3-у елементу
    
         // вписываем UIN (только СВОЙ - укажем явно,что из модуля Main.pas)
         PLONG(@(b[i]))^ := main.UIN;    inc(i,4);
         // ТИП запроса
         PWORD(@(b[i]))^ := swap($D007);   inc(i,2);
         // придумаем себе COOKIE 
         // (можно и по-проще, но в настоящей аське
    // COOKIE имеет такой вид XX00)
    Cookie := random($FF) shl 8; PWORD(@(b[i]))^ := swap(Cookie); inc(i,2); // ПОДТИП запроса PWORD(@(b[i]))^ := swap($1505); inc(i,2); // добавляем три текстовые строки (First, Last, Nick) // у AOL новый тип строк наверное :) // впереди - длина строки, а в конце #0 // (что-то одно из них убрали бы) // длина строки PWORD(@(b[i]))^ := length(FN)+1; inc(i,2); // сама строка FirstName MOVE(FN[1],b[i],length(FN)); inc(i,Length(FN)); // завершающий #0 PBYTE(@(b[i]))^ := 0; inc(i,1); // LastName PWORD(@(b[i]))^ := length(LN)+1; inc(i,2); MOVE(LN[1],b[i],length(LN)); inc(i,Length(LN)); PBYTE(@(b[i]))^ := 0; inc(i,1); // NickName PWORD(@(b[i]))^ := length(NN)+1; inc(i,2); MOVE(NN[1],b[i],length(NN)); inc(i,Length(NN)); PBYTE(@(b[i]))^ := 0; inc(i,1); // дозаполним "ненужную" длину в начале массива PWORD(@(b[0]))^ := i-2;
    // создаем FLAP-пакет P:=CreatePacket(2,SEQ); // добавляем SNAC(15,2) SNACAppend(p,$15,$2); // добавляем TLV(1) с данными из промежуточного массива TLVAppend(p,1,i,@b); // шлем запрос Form1.PacketSend(p); // пишем в Memo M(Form1.Memo,'> Search Detail: Nick:'+NN+ ' First:'+FN+ ' Last:'+LN+' '+ 'Cookie:$'+inttohex(Cookie,4)); end;

    Запросы других подтипов передаются аналогично. С небольшими вариациями. Оновременно можем передавать на сервер много запросов. Сервер разберется. Ведь в каждом нашем запросе есть уникальное(ый) Cookie (а также и RequestID в SNAC-заголовке). Сервер пометит свои пакеты-ответы этими же опознавательными знаками.
    Я лично делаю проверку(сверку) только по Cookie. Выдавая запрос, запоминаю Cookie. А когда приходит ответ от сервера, то процедура-обработчик SNAC_15_3 просто использует WinAPI функцию PostMessage для передачи ответа окну, которое выдало запрос. В параметрах PostMessage указан Cookie из ответа сервера. Какое окно его опознает - значит тому окну и предназначен ответ.

    Работа процедуры-обработчика SNAC_15_3 уже ранее рассматривалась. Сейчас она просто дополнена новыми блоками, обрабатывающими новые ответы сервера. Следует упомянуть, что на один (единственный) наш запрос сервер присылает сразу целый массив из SNAC-ответов. Это типичная ситуация.
    Например: запрашиваем Инфо о клиенте SNAC(15,2) [подтип запроса B204].
    В ответ получим сразу восемь SNAC-ответов.

    Вот их краткие названия-описания:

  • main-home-info

  • homepage-more-info

  • more-email-info

  • additional-info

  • work-info

  • about

  • personal-interests

  • past-background


  • Все полученные данные теперь сохраняются в файле <UIN>.dat
    Назад Содержание Дальше