|
|
Создаем свой ICQ-клиент
Основны понятия
Собственно говорить мы будем об одном из последних восьмом протоколе ICQ. Говоря откровенно ничего сложного там нет, ну разве что немного все может показаться запутанным на первый взгляд, но это только сначала.
FLAP-заголовки
Все данные, которыми обменивается Аська состоят из ФЛАПов, что же это такое, давайте разбираться. Итак ФЛАП - это некая последовательность данных, которая описывает данные передающиеся между сервером и клиентом в оба направления. Привидем пример дампа ответа сервера при соединении для авторизации (тут и далее данные приведены в HEX):
|
FLAP-Заголовок
|
|
|
|
2A
xx
xx xx
xx xx
|
byte
byte
long
long
|
Начало FLAP-пакета
Канал передачи данных
Номер запроса
Длина данных
|
|
|
|
XX...
|
Данные |
|
2A 01 59 30 00 04 00 00 00 01
Как же читатется пакет, собственно говоря как мы видим, длина FLAP-заголовка равна 6 байтам, т.е. предполагается следующий алгоритм чтения:
1. установить курсор на первом байте
2. Проверить равен ли он 2A
3. Определить канал связи 01
4. Проверить номер запроса 59 30 (не обязательно), сервер как и клиент должны после отправки каждого паета увеличивать этот номер на единицу, если выясняется, что номера идут не последовательно связь разрывается.
5. Определить длину пакета 00 04 т.е. 4 байта
6. Посмотреть равна ли длина всего пакета "6 + длина данных"
а). Если равна, выделить данные
DATA = (Right(StartData, Len(StartData)-6))
DATA = 00 00 00 01
б). Если не равна, сохранить StartData во временный буфер и ожидать прихода остальных данных. Например так:
Buffer=Buffer & StartData
Чтобы не говорить в пустую, предлагаю сделать небольшой проект который состоит из пары строк и посмотреть как ведет себя ICQ-сервер. Итак,
Открываем Visual Basic, создаем новый проект, жмем Ctrl+T находим Microsoft Winsock Control 6.0 выбирам его, добавляем на форму и называем егo Win1.
'## Коннектим винсок к серверу авторизации ICQ
Private Sub Form_Load()
Win1.Close
Win1.Connect "login.icq.com", 5190
End Sub
'## Функция которая вам сильно пригодится на этапе отладки
Function ShowHex(txt As String) As String
MS = ""
For I = 1 To Len(txt)
PP = Hex(Asc(Mid(txt, I, 1)))
MS = MS + IIf(Len(PP) = 1, "0" & PP, PP) & " "
Next I
ShowHex = MS
End Function
'## Получаем ответы сервера
Private Sub Win1_DataArrival(ByVal bytesTotal As Long)
Dim DATA As String
Win1.GetData DATA
Caption = ShowHex(DATA)
End Sub
Жмем F5 и в заголовке формы видим то что нам прислал сервер. Это так называемое приглашение к авторизации. Можно немного усложнить наш проект и добавить функкцию чтения FLAP-заголовка, она конечно не притендует на уникальность но со своей задачей (демонстрационной) она справляется:
'## опишем тип для ознакомления:)
Private Type FLAP_HEAD
ChannelID as byte
SEQ as long
DataLen as long
Data as string
End Type
'## Функция чтения ФЛАП-пакета
Function ReadFlap(txt as String) as FLAP_HEAD
PP=1
IF asc(Mid(txt,PP,1))<>&H2A then Exit Function
With ReadFlap
.ChannelID = Asc(Mid(txt, PP+1, 1))
.SEQ = CnvStrToLong(Mid(txt, PP+2, 2))
.DataLen = CnvStrToLong(Mid(txt, PP+4, 2))
.Data = Right(Mid(txt, PP+6, .DataLen))
End with
End Function
'## Функция преобразования STR в LONG
Function CnvStrToLong(txt As String) As Long
CnvStrToLong = 0
For I = 1 To Len(txt)
f = Asc(Mid(txt, Len(txt) + 1 - I, 1))
CnvStrToLong = CnvStrToLong + f * 256 ^ (I - 1)
Next I
End Function
Теперь, если передать в ReadFlap данные, полученные от сервера ICQ, то мы получим разложенный флап-заголовок в виде объекта и данные. Если ты уже заметил, здесь используется много собственных функций, так вот без них оказывается никак нельзя, просто некоторые типы данных не доступны в Бейсике и приходится немного придумывать своего. Возможно у тебя получится упростить механизмы преобразований, тогда прошу сразу мылить мне;)
В соответствии со спецификацией протокола, всего может быть определено 4 канала:
1 - Авторизация
2 - Передача данных
3 - Служебный канал (не используется)
4 - Ошибки
Чаще всего будет использоваться второй канал, затем первый и не дай бог - четвертый, третий тебе наверное и не встретится. Определившись с каналом можно перейти к непосредственному анализу данных. Подробнее об этом на следующем занятии.
E-Mail: supports@aaanet.ru
|
|
|
|
|
|