Забытый протокол от AOL Вольф Данияр Спецвыпуск: Хакер, номер #058, стр. 058-078-3 Итак, все это хозяйство собирается в один буфер и отправляется на сервис AIM ("Фрагмент 4"). Если все сделано правильно, то сервер должен прислать contact list и предоставить заветный статус online. Остается придумать, как реализовать прием и отправку сообщений. С помощью главного цикла, через который мы будем получать все поступающие сообщения и выводить их на консоль ("Фрагмент 6"). Если потребуется отправить сообщение, сделаем прерывание с клавиатуры, и нам будет предоставлен терминал по вводу текста (см. "Фрагмент 7"). Формировать AIM-пакет с сообщением будем с помощью функции encode_toc_send_im, а все поступающие в поток данные занесем в буфер buffer. Так как я в основном работаю в среде UNIX и клиент у меня консольный, я применил систему сигналов. Когда код программы уйдет в цикл, ожидая входящие сообщения AIM-пакетов, мы установим асинхронное прерывание на тот случай, если вдруг захочется послать сообщение (см. функцию onintr). Кодим-покодим Ну что же, думаю, с теоретической частью покончено, и можно перейти непосредственно к водным процедурам, а именно к кодингу. Правда, весь код не мог влезть в статью (это и не нужно), поэтому многое было выкинуто. Полная версия исходника есть на диске к журналу, поэтому начнем сразу с определения сервера и порта AIM, куда нужно подключиться, сервер и порт авторизации на нем должен авторизовать сервис AIM: #define TOC_HOST "toc.oscar.aol.com" #define TOC_PORT 9898 #define AUTH_HOST "login.oscar.aol.com" #define AUTH_PORT 5190 // Язык(локаль) на котором должен общаться // наш клиент #define LANGUAGE "english" // Версия нашего клиента, может быть любое слово. #define REVISION "Miranda" /* Переменная для шифрования (xor'ирования) нашего пароля, шифровать пароль будем при помощи функции roast_password. */ #define ROAST "Tic/Toc" /* Определяем типы флэп-пакета */ #define TYPE_SIGNON 1 #define TYPE_DATA 2 #define TYPE_ERROR 3 #define TYPE_SIGNOFF 4 #define TYPE_KEEPALIVE 5 /* Первая команда, которая должна уйти на сервер (см. функцию send(sock, FLAPON, sizeof(FLAPON), 0)) */ #define FLAPON "FLAPON\r\n\r\n" //Простой макрос, который будет записывать в буфер buf значения в один байт. #define writeb(buf, value) (*buf=value, buf++) /* Простая функция для записи в буфер двухбайтовых значений (2x8 разрядов). Не забываем, что в Сети существует сетевое следование байт, поэтому мы делаем конверсию функцией htons. */ static char *writew(char *buf, u_int16_t value) { *((u_int16_t *)buf)++ = htons(value); return buf; } /* Простая функция для записи в буфер четырехбайтовых значений (4x8 разрядов). Опять же делаем конверсию, но уже при помощи функции htonl */ static char *writel(char *buf, u_int32_t value) { *((u_int32_t *)buf)++ = htonl(value); return buf; } /* Простая функция для записи в буфер строковых значений (например отправляемое текстовое сообщение). Конверсию делать не будем, так как запись в буфер будет происходить с помощью функции memcpy по байтам. Все необходимое она сделает сама. |