Форум программистов CODEBY.NET Хостинг в Беларуси — Active Technologies

Разработка бизнес сайтов

Нужны клиенты? Тогда сюда быстрее...
X   Сообщение сайта
(Сообщение закроется через 2 секунды)

Здравствуйте, гость ( Вход | Регистрация )




> Mra протокол.помогите разобраться
ReindeeR
Вставить ник
сообщение 3:04:2008, 12:52
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 39
Регистрация: 3:04:2008
Пользователь №: 16 361



Репутация: - 1 +


Вы уж извините,что так сразу,с такими вопросами тупыми врываюсь)

Решил попрактиковаться в работе с сетью и с сокетами,
выбор мой пал на создание примитивного mail.ru агента,
консольное приложение,которое может хотя бы могло законнектится к серверу,
и пройти авторизацию юзера.Сейчас опишу,как и что делаю.
Сначала подключаю winsock.2 и подгружаю библиотеку ws2_32.Lib
адрес и порт,по которому коннектится
Код
#define PORT 2042
#define SERVERADDR "mrim.mail.ru"

Функцией WSAStartup() подготавливаю для работы winsock2
Создаю сокет,
Код
my_sock=socket(AF_INET,SOCK_STREAM,0);

заполняю структуру sockaddr_in
Код
sockaddr_in dest_addr;
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(PORT);
HOSTENT *hst;

далее преобразуем адрес
Код
hst=gethostbyname ( SERVERADDR );
( ( unsigned long   * ) &dest_addr.sin_addr ) [ 0 ] =( ( unsigned long    ** ) hst->h_addr_list ) [ 0 ] [ 0 ];

сам коннект
Код
connect(my_sock,(sockaddr*) &dest_addr,sizeof(dest_addr));

Вот отсюда и начинаются все непонятки,что делать,как отсылать и принимать.

вот описание протокола
http://agent.mail.ru/protocol.html

Все проблемы начались с непонятного инклюда,в файле,который выложен в описании протокола,
Код
#include

и все,а что собственно нужно подключать??,не сказано=(
ну я удалил эту строчку за ненадобностьюsmile.gif

идем далее,сказано,в том же описании,что
"После установки tcp-соединения клиент обязан сразу послать MRIM_CS_HELLO"
Вот и главная проблема.Как отправлять,прнимать,и вообще как их создавать,эти пакеты?
Код
Заголовок пакета
{
    u_long      magic; // Magic
    u_long      proto; // Версия протокола
    u_long      seq; // Sequence
    u_long      msg; // Тип пакета
    u_long      dlen;  // Длина данных
    u_long from; // Адрес отправителя
    u_long fromport; // Порт отправителя
    u_char reserved[16]; // Зарезервировано
}

По порядку,
magic,это мне понятно
в файле proto.h есть константа
Код
#define CS_MAGIC    0xDEADBEEF


версия протокола,тоже понятно откуда брать
Код
#define PROTO_VERSION_MAJOR     1
#define PROTO_VERSION_MINOR     7
#define PROTO_VERSION ((((u_long)(PROTO_VERSION_MAJOR))<<16)|(u_long)(PROTO_VERSION_MINOR))


Sequence,а вот что это такое,я так и не понял.
тип пакета,как я понял,тут и надо указывать MRIM_CS_HELLO
Адрес и порт отправителя,тут что указывать?

Ладно,допустим я разобрался что и где писать,
а как называть пакет?
из файла
Код
typedef struct mrim_packet_header_t
{
    u_long      magic; // Magic
    u_long      proto; // Версия протокола
    u_long      seq; // Sequence
    u_long      msg; // Тип пакета
    u_long      dlen;  // Длина данных
    u_long from; // Адрес отправителя
    u_long fromport; // Порт отправителя
    u_char reserved[16]; // Зарезервировано
}
mrim_packet_header_t;

вот тут я окончательно запутался.
mrim_packet_header_t это тип структуры,и имя пакета одновременно?
Код
int send(SOCKET s,char* buf,int len,int flags);

компилятор ругается,при попытке отправить пакет,
приводить его к типу char* и отправлять?или как быть?
та же история и при приеме данных.

Ну вот,все сказал вроде,что непонятно.
Если вы дочитали до конца весь этот бред,и не поленились посмотреть описание
протокола,огромнейшая просьба,хоть как-то помочьrolleyes.gif
Подняться вверх 
 
Сообщение #1
2 страниц V  < 1 2  
Новая тема 
Ответов (30 - 35)
ReindeeR
Вставить ник
сообщение 19:04:2008, 23:25
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 39
Регистрация: 3:04:2008
Пользователь №: 16 361



Репутация: - 1 +


Код
iResult=recv(mySock,(char*)&packFrom,sizeof(packFrom),0);           //Пришел пакет
    if(iResult>0 && packFrom.msg == MRIM_CS_USER_INFO)
    {
        int sizeData=packFrom.dlen;                            //записываю скока байт обещают
        int realSizeData=0;                         //в переменную будет дописываться размер принятых данных

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);         //в bufSize записываем длину следующей строки.
        char msgTotal[4096];
        iResult=recv(mySock,msgTotal,bufSize,0);        //в переменной msgTotal будет строка "MESSAGES.TOTAL"
        realSizeData+=iResult;

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);     //в bufSize записываем длину следующей строки.
        char numMsgTotal[4096];
        iResult=recv(mySock,numMsgTotal,bufSize,0);      //приходит кол-во MESSAGES.TOTAL в виде строки.В моем случае это 81
        realSizeData+=iResult;
        printf("%s = %s\n",msgTotal,numMsgTotal);

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);        
        char msgUnread[4096];
        iResult=recv(mySock,msgUnread,bufSize,0);          //строка "MESSAGES.UNREAD"
        realSizeData+=iResult;

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);     //Количетсво непрочтенных писем
        char numMsgUnread[4096];
        iResult=recv(mySock,numMsgUnread,bufSize,0);         //приходит кол-во MESSAGES.UNREAD в виде строки.В моем случае это 1
        realSizeData+=iResult;
        printf("%s = %s\n",msgUnread,numMsgUnread);

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);       //получаем строку "MRIM.NICKNAME
        char nickName[4096];
        iResult=recv(mySock,nickName,bufSize,0);                                  
        realSizeData+=iResult;

        iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);     //ну и получаем сам ник
        char nick[4096];
        iResult=recv(mySock,nick,bufSize,0);
        realSizeData+=iResult;
        printf("%s = %s \n",nickName,nick);

        printf("Ожидаемый размер данных= %d \n Размер полученных данных = %d \n",sizeData,realSizeData); // чтобы сразу было видно.
    }

Цитата
в результате получаем
MESSAGES.TOTAL = 81
MESSAGES.UNREAD = 1
MRIM.NICKNAME = ***********
Ожидаемый размер данных= 80
Размер полученных данных = 56


1 вопрос,нафига такие вот char nickName[4096]; ?
потому что если массив будет меньше,даже при 2048,
в конец добавляется много всяких значков и прочей лабуды,
иногда вообще захавает конец строки и всяких значков напехается.
Почему,не знаю,вот и спрашиваю. unsure.gif

ну а так вроде все по коду понятно остальное.
извиняюсь за названия переменных rolleyes.gif

Сообщение отредактировал ReindeeR - 19:04:2008, 23:26
Подняться вверх 
 
Сообщение #31
Yason
Вставить ник
сообщение 20:04:2008, 01:03
Цитата Ответить 


Продвинутый
**

Группа: Программист
Сообщений: 139
Регистрация: 27:02:2004
Пользователь №: 296



Репутация: - 6 +


Код
iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);         //в bufSize записываем длину следующей строки.
realSizeData+=iResult;   //<--- Добавить это. И так шесть раз. 6*4 = 24 "потерянных" байта
char msgTotal[4096];    
iResult=recv(mySock,msgTotal,bufSize,0);        //в переменной msgTotal будет строка "MESSAGES.TOTAL"
realSizeData+=iResult;


Насчёт выделения 4кБ для буфера - можно и меньше, конечно - лишь бы хватало.
А ещё лучше -- выделять ровно столько, сколько необходимо:
Код
char* msgTotal = (char*)malloc(bufSize+1);
msgTotal[bufSize]='\0';

Сразу получится нормальная СИшная строка. Только потом нужно вовремя освободить память: free(mgsTotal).
Подняться вверх 
 
Сообщение #32
ReindeeR
Вставить ник
сообщение 20:04:2008, 01:05
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 39
Регистрация: 3:04:2008
Пользователь №: 16 361



Репутация: - 1 +


в том то и дело,
указываю меньше 4 кб,
всякая фигня оказывается в строке
Подняться вверх 
 
Сообщение #33
Yason
Вставить ник
сообщение 20:04:2008, 01:32
Цитата Ответить 


Продвинутый
**

Группа: Программист
Сообщений: 139
Регистрация: 27:02:2004
Пользователь №: 296



Репутация: - 6 +


Фигня, очевидно, показывается из-за того, что C/C++ понимает строки как массивы, завершающиеся нулём, а mail.ru их понимает как (4 байта длины)+(массив указанной длины, без нуля в конце).
Подняться вверх 
 
Сообщение #34
ReindeeR
Вставить ник
сообщение 20:04:2008, 01:42
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 39
Регистрация: 3:04:2008
Пользователь №: 16 361



Репутация: - 1 +


ну ладно,это не так важно пока что.
что делать с этими пакетами,которые идут как-то не так.
щас попробую до конца все принять,пока не успокоятся))
Подняться вверх 
 
Сообщение #35
ReindeeR
Вставить ник
сообщение 21:04:2008, 14:27
Цитата Ответить 


Новенький
*

Группа: Новенький
Сообщений: 39
Регистрация: 3:04:2008
Пользователь №: 16 361



Репутация: - 1 +


Yason
вам памятник надо ставить за истреблении нубства в программировании. smile.gif
спс огромное,дальше надеюсь сам разберусь уж как-нибудь. wacko.gif
Подняться вверх 
 
Сообщение #36


2 страниц V  < 1 2
Быстрый ответ  Ответить  Новая тема 

> Быстрый ответ
Полужирный
Курсив
Подчеркнутый
Вставить изображение
Смайлики
Цитата
Код
 
 Отправлять уведомления об ответах на e-mail |  Включить смайлики |  Добавить подпись
   

 

RSS Текстовая версия Сейчас: 5:09:2008 - 07:16
с нами можно связаться по:
телефону: +375-(29)-632-60-67
e-mail:info@codeby.net