Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум программистов _ Общие вопросы по С и С++ _ Mra протокол.помогите разобраться

Автор: ReindeeR 3:04:2008, 12:52

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

Решил попрактиковаться в работе с сетью и с сокетами,
выбор мой пал на создание примитивного 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://forum.codeby.net/go.php?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

Автор: Yason 15:04:2008, 03:08

Ничего себе тренировочная задачка! wink.gif

Судя по всему,

{
    u_long    magic;    //волшебный ключ, указывающий на то, что это действительно пакет MMP
    u_long    proto;  //версия MMP, поддерживаемая отправителем пакета
    u_long    seq;  //номер отправляемой команды в текущем соединении. Ответ на команду должен иметь тот же номер, что и сама команда.
    u_long    msg;  //тип пакета, номер команды и/или ответа
    u_long    dlen;  //длина данных пакета (без учета заголовка)
    u_long    from;  //ip (в inet_aton() формате) с которого установлено соединение
    u_long    fromport;  //порт (в inet_aton() формате) с которого установлено соединение
    u_char    reserved[16];
}

MRIM_CS_HELLO, как я понял, нужно прописать в seq. Затем отправляешь этот пакет (по сути, только заголовок, ибо в MRIM_CS_HELLO доп. данные не предполагаются) (да, явно приведя к типу char*) и ждёшь, когда тебе придёт ответ от сервера в виде заголовка (с msg=MRIM_CS_HELLO_ACK) и параметров (структура mrim_connection_params_t. К слову, это только тип структуры, а не имя пакета). Ну и дальше, как там описано.

P.S. Протокол этот впервые вижу, так что могу в чём-то заблуждаться.

Автор: ReindeeR 15:04:2008, 12:57

не,seq это просто номер команды,в ответе он должен быть таким же,короче это не очень важный параметр))
MRIM_CS_HELLO надо отправлять первым,указывая в msg.
отправить у меня получается,а вот в ответ приходит чет непонятное.
И потом как мне узнать,что пришло?
Если принять пакет с msg=MRIM_CS_HELLO_ACK,
то как принять mrim_connection_params_t ?
это же две разные структуры,и как мне они придут в одном ответе? huh.gif
короче,как было ничего непонятно,так все и осталось)
лан,ща буду мучаться

Автор: Yason 16:04:2008, 01:22

ReindeeR
Каждый пакет состоит из заголовка (mrim_packet_header_t) и следующих за ними данных (зависят от команды, для MRIM_CS_HELLO_ACK - mrim_connection_params_t; для некоторых команд, типа MRIM_CS_HELLO - отсутствуют). Размер передаваемых данных нужно указывать в mrim_packet_header_t.dlen. Ну, это, я думаю, и так понятно smile.gif
А ответ можно (и нужно) считывать за несколько приёмов. Сначала заголовок размером sizeof(mrim_packet_header_t), затем по считанному заголовку определяешь, какого типа данные ожидаются, создаёшь буфер соответствующего типа, и считываешь из сокета в него остаток пакета.

Как узнать что "вам пакет от сервера" - либо тупо ждать после отправки запроса, либо тоже самое, только умно - в отдельном потоке (thread) с контролем таймаута.

Автор: ReindeeR 16:04:2008, 03:42

в ответ приходит какая-то фигня размеров в 19 байтов. huh.gif
зы.причем один раз

ап.
mrim_connection_params_t 4 байта,
можно попробовать вынять эти 4 байта с начала или конца принятых 19 wacko.gif

зы.
а как это сделать? blink.gif

Автор: Yason 16:04:2008, 13:18

ReindeeR
Могу поспорить, что эта фигня складывается в циферки типа "194.186.55.27:2041" wink.gif

Цитата
Рекомендованный для соединения сервер в любой момент времени можно получить в текстовом формате ip:port по адресу mrim.mail.ru:2042 и mrim.mail.ru:443

Зайди браузером на ]]>http://forum.codeby.net/go.php?http://mrim.mail.ru:2042]]>, и воочию увидишь, что именно ты получаешь smile.gif

P.S. Поздравляю, значит приём-передача уже как-то работают!

Автор: ReindeeR 16:04:2008, 13:42

Цитата(Yason @ 16:04:2008, 16:18 ) *
ReindeeR
Могу поспорить, что эта фигня складывается в циферки типа "194.186.55.27:2041" wink.gif

Зайди браузером на ]]>http://forum.codeby.net/go.php?http://mrim.mail.ru:2042]]>, и воочию увидишь, что именно ты получаешь smile.gif

P.S. Поздравляю, значит приём-передача уже как-то работают!

ааааа
я как дятел больше 10 дней пытаюсь достучаться по этому адресу и выпытать ответ.
мда..внимательнее читать надо unsure.gif
щас буду пробовать коннектиться на получаемый адрес rolleyes.gif ))

Автор: ReindeeR 16:04:2008, 22:29

Новая проблемка))
не получается установить коннект с сервером.
Точнее получается,только не совсем правильно.
полученный адрес,по которому нужно соединятся с сервером,
находится в переменной IPaddr в формате "194.186.55.17:2041".
разделяю их с помощью strtok

ip=strtok(IPaddr,":");
port=strtok('\0',":");

далее засовываю в структуру sockaddr_in dest_addr
dest_addr.sin_family=AF_INET;
dest_addr.sin_addr.s_addr=inet_addr(ip);
dest_addr.sin_port=htons((u_short)port);

ну и соединяюсь connect(my_sock,(SOCKADDR*) &dest_addr,sizeof(dest_addr));
ну и собственно ничего не соединяется.
еще при компиляции выскакивает варнинг
cast from pointer to integer of different size
ругается на строчку,где функция htons()
в чем опять проблема?и как собственно ее решить?
пока сделал так,посмотрел один из адресов,которые выдаются
и объявил константами,
#define,не знаю как это правильно называется))

Автор: Yason 17:04:2008, 01:11

Цитата(ReindeeR @ 17:04:2008 - 02:29) *
cast from pointer to integer of different size
ругается на строчку,где функция htons()

Ну, ругается, очевидно, потому, что не желает char* с номером порта переводить в u_short путём приведения типов.
Видимо, просит atoi(port) smile.gif

Автор: ReindeeR 17:04:2008, 03:16

С портом разобрался))
теперь проблема с приемом данных.
цитата из описания.

Цитата
После установки tcp-соединения клиент обязан сразу послать MRIM_CS_HELLO, дождаться MRIM_CS_HELLO_ACK

hello отправляю,а в ответ тишина...
собственно сделал вывод,что пакет с MRIM_CS_HELLO у меня отправляется криво,раз ответа нет.
делаю так:

mrim_packet_header_t packHello;
packHello.magic=CS_MAGIC;      //формирование пакета
packHello.proto=PROTO_VERSION;
packHello.seq=i;
packHello.msg=MRIM_CS_HELLO;
packHello.dlen=sizeof(mrim_packet_header_t);
packHello.from=0;
packHello.fromport=0;
send(my_sock,(char*)packHello,bufsize,0);//отправляется 44 байта,как и должно по идее.

//далее попытка принять пакет.
    do
    {
        char *buffer;
        int iResult=recv(mySock,buffer,bufsize,0);
        if(iResult>0)
            cout << "Размер полученных данных="<< iResult  << endl;
        else if(iResult==0)
            cout << "Прием данных завершен.\n";
        else
            cout << WSAGetLastError() <<endl;
    }while(iResult>0);

при попытке принять данные все висит секунд 50,ничего не принимая,
а потом "Прием данных завершен." unsure.gif

Автор: Yason 17:04:2008, 12:29

packHello.from=0;
packHello.fromport=0;

По идее, там должны быть IP и порт отправителя (т.е. клиента).


send(my_sock,(char*)packHello,bufsize,0);

Если мне не изменяет склероз, должно быть
send(my_sock,(char*)&packHello,bufsize,0);


Далее, учитывая, что "длина данных пакета (без учета заголовка)"
packHello.dlen=0;


И ответ, как мне кажется, было бы логичнее ждать в таком виде:
mrim_packet_header_t buffer;
int iResult=recv(mySock, (char*)&buffer, bufsize, 0);

Автор: ReindeeR 17:04:2008, 14:46

Цитата(Yason @ 17:04:2008 - 16:29) *
По идее, там должны быть IP и порт отправителя (т.е. клиента).

IP указывать не надо,а вот порт оказалось обязательно,просто у кого не спрашивал,все говорили типа устанавливается все в ноль mad.gif

ага,поставил ноль.
Цитата(Yason @ 17:04:2008 - 16:29) *
Далее, учитывая, что "длина данных пакета (без учета заголовка)"
packHello.dlen=0;

ага,поставил ноль.
Ну вот после этих исправлений данные пришли.
В размере 48 байтов.
44 байта заголовок,и 4 байта данные,mrim_connection_params_t
Цитата(Yason @ 17:04:2008 - 16:29) *
send(my_sock,(char*)&packHello,bufsize,0);

опечатался.все так и есть.
Цитата(Yason @ 17:04:2008 - 16:29) *
И ответ, как мне кажется, было бы логичнее ждать в таком виде:

обычно так и принимал,просто экспериментировал smile.gif
ну вот,данные получены,проверил,все правильно,msg==MRIM_CS_HELLO_ACK
dlen==4 байта,что и ожидалось.
Ну и очередной вопрос,как мне достать эти четыре байта,mrim_connection_params_t.ping_period?

Автор: Yason 17:04:2008, 15:01

Так а в чём проблема?

mrim_packet_header_t header;
int iResult=recv(mySock, (char*)&header, sizeof(header), 0);
mrim_connection_params_t params;
iResult=recv(mySock, (char*)&params, sizeof(params), 0);

Автор: ReindeeR 17:04:2008, 15:31

не знал,что так можно. unsure.gif
интервал получил,30 сек).
далее авторизация юзверя.

Цитата
Пакет: Авторизация

Имя пакета: MRIM_CS_LOGIN2
Тип пакета: cs
Параметры:

LPS ## login ## email авторизующегося пользователя
LPS ## password ## пароль
UL ## status ## статус (см. MRIM_CS_CHANGE_STATUS)
LPS ## user_agent ## текстовое описание клиента пользователя, например "Mail.Ru Miranda Plugin v 1.0"

как мне эти данные присоединть к пакету?

и еще.
как отправлять пакет c MRIM_CS_PING каждые 30 секунд?
в winAPI понятно,таймер и все.
а как в консоли это сделать?

Автор: Yason 17:04:2008, 21:40

Цитата(ReindeeR @ 17:04:2008 - 18:31) *
как мне эти данные присоединть к пакету?

Аналогично чтению - в несколько этапов. Сначала отправляешь заголовок, потом длину логина, потом сам логин, потом длину пароля, и т.д. Разумеется, dlen должен быть равен суммарной длине данных (исключая заголовок).

Цитата(ReindeeR @ 17:04:2008 - 18:31) *
как отправлять пакет c MRIM_CS_PING каждые 30 секунд?

Либо SetTimer(NULL, 0, 30000, SendPing()), либо создать отдельный поток и в нём
while (!quit) {
    SendPing();
    Sleep(30000);
}

В обоих случаях, в реальном приложении нужно синхронизировать отправку, чтобы MRIM_CS_PING не был случайно отправлен между заголовком и данными другого пакета.

Автор: ReindeeR 18:04:2008, 01:28

ыыы,авторизировался cool.gif )))
щас буду пробовать таймер установить.
Потоки=темный лес для меня пока что.

зы.
как синхронизировать все это,чтобы косяков не было? wacko.gif

ап.
Таймер использовать не получилось,так как он сразу убивается у меня.
Всмысле запускаю таймер,выполняется только первый раз при запуске,
а потом программа завершается,и абсолютно пофиг,что там таймер запущен.

ну а поток создать у меня тем более не получается.
ошибок вылезает хз скока.
Мне надо передать в функцию потока сокет и интервал пинга.
А если учитывать то,что про потоки я прочитал несколько часов назад,
для меня эта задача вообще невыполнимая ph34r.gif

Автор: Yason 18:04:2008, 13:56

Цитата(ReindeeR @ 18:04:2008 - 01:28) *
Всмысле запускаю таймер,выполняется только первый раз при запуске,
а потом программа завершается,и абсолютно пофиг,что там таймер запущен.

Ну, программа и не должна ждать таймер, поэтому её нужно зациклить. А учитывая, что для нормальной работы таймера "you need to dispatch messages in the calling thread" © WinAPI, зациклить программу можно как-нибудь так:
/* Acquire and dispatch messages until a WM_QUIT message is received. */
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}


Цитата(ReindeeR @ 18:04:2008 - 01:28) *
как синхронизировать все это,чтобы косяков не было?

После вдумчивого чтения хелпа по SetTimer, оказалось, что таймер работает через сообщения в основном потоке, поэтому синхронизировать его не нужно.
При многопоточности, конечно, всё не так радужно smile.gif

Автор: ReindeeR 18:04:2008, 14:41

дело в том,что у меня приложение консольное,
цикл обработки сообщений никуда не запехаешь))

Автор: Yason 18:04:2008, 15:55

Ну не знаю, не знаю... Это - работает smile.gif

CODE
int CALLBACK tick()
{
cout<<"tick\n";
}

int main(int argc, char* argv[])
{
SetTimer(NULL, 0, 1000, tick);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

Автор: ReindeeR 18:04:2008, 18:41

ну тогда как передать мне в функцию tick() параметры?))

ап.
извиняюсь,как обычно туплю smile.gif

Цитата(Yason @ 18:04:2008, 19:55 ) *
Ну не знаю, не знаю... Это - работает smile.gif
int CALLBACK tick()
{
cout<<"tick\n";
}

на такую функцию компилятор матерился.
пришлось городить вот так
void CALLBACK tick(HWND ccc,UINT iii,UINT aaa,DWORD bbb)


mrim_packet_header_t packPing;
    packPing.magic=CS_MAGIC;
    packPing.proto=PROTO_VERSION;
    packPing.seq=0;
    packPing.msg=MRIM_CS_PING;
    packPing.dlen=0;
    packPing.from=0;
    packPing.fromport=2041;
    int iResult=send(my_sock,(char*)&packPing,sizeof(packPing),0);

новая проблема.
при отсылке такого пакета сразу же обрывается соединение.

Автор: Yason 18:04:2008, 21:47

packPing.seq=0;

А ноль ли?.. huh.gif

Автор: ReindeeR 18:04:2008, 22:00

и ноль,и не ноль пробовал.

зы.
наверное дело в том,что там еще заголовок стучиться+80 байт blink.gif
оказалось это пришли данные о только что подсоединившеся юзвере,
его ник,сколько писем и т.д.Обнаружил чисто случайно это/
D описании протокола ниче по этому поводу не сказано,
типа после автризации к вам придет MRIM_CS_USER_INFO. mad.gif

Или не влияет,что данные не все еще приняты и идет отправка?

Автор: Yason 19:04:2008, 13:32

ReindeeR

Цитата
Взаимодействие с сервером происходит поверх постоянно установленного tcp-соединения посредством асинхронного обмена командами. Инициатором установления соединения может быть только клиент, команды могут посылаться как клиентом, так и сервером.

Так что, по идее, приложение должно быть всегда готовым к приёму (непрошенных) пакетов с сервера. Можно уже писать здоровый switch для обработки команд с сервера smile.gif

Цитата(ReindeeR @ 19:04:2008 - 02:00) *
Или не влияет,что данные не все еще приняты и идет отправка?

]]>http://forum.codeby.net/go.php?http://en.wikipedia.org/wiki/Internet_socket]]> утверждает, что "socket-to-socket virtual connection, is established with a remote client, providing a duplex byte stream", т.е. данные могут идти одновременно в обоих направлениях.

Автор: ReindeeR 19:04:2008, 17:24

Пытаюсь получить информацию о пользователе.
Описание

Цитата
Пакет: Информация о пользователе

Имя пакета: MRIM_CS_USER_INFO
Тип пакета: sc
Параметры:

LPS, LPS, ... ##name1, value1, name2, value2, ... ## дополнительная информация о пользователе, имя параметра, значение параметра, имя параметра, значение параметра, ... На данный момент определены MESSAGES.TOTAL - количество писем в ящике, MESSAGES.UNREAD - количество непрочитанных писем в ящике, MRIM.NICKNAME - ник пользователя

В заголовке указан размер данных в 80 байт.
получаю MESSAGES.TOTAL, MESSAGES.UNREAD и MRIM.NICKNAME
и того 56 байт.Думаю че за фигня,пытаюсь получить длину следующих данных.
iResult=recv(mySock,(char*)&bufSize,sizeof(bufSize),0);
cout << bufSize << endl;

и вот это приходит
bufSize=3735928559
blink.gif
где я им такой буфер возьму? mad.gif ))
WSAGetLastError() молчит,все в порядке.

Автор: Yason 19:04:2008, 18:24

Цитата(ReindeeR @ 19:04:2008 - 21:24) *
3735928559

Интересно, а на что это число похоже, если его перевести в hex? dry.gif

Автор: ReindeeR 19:04:2008, 19:13

deadbeef
это че?? blink.gif

Автор: Yason 19:04:2008, 19:38

Ох-хо-хо... rolleyes.gif

#define CS_MAGIC    0xDEADBEEF        // Клиентский Magic ( C <-> S )

Это начало нового пакета...

Автор: ReindeeR 19:04:2008, 20:05

unsure.gif мда..
Я когда прочитал deadbeef я чуть со стула не упал,
о том,что это они так мэджик обозначили мне и в голову уже придти не могло.
шутники мля..

Автор: ReindeeR 19:04:2008, 21:59

я чето не понял.
пришел заголовок MRIM_CS_USER_INFO
размер пакета=80 байт.
принимаю данные,вдруг туда вклинивается заголовок MRIM_CS_USER_INFO
размер пакета=28 байт.
56 из обещанных 80 я принял,
80-56=24 байта еще должны по идее придти.
но приходит еще пакет размером размером 28.
итого перебор 4 байта.
Еще как я догадываюсь,скоро припрется контакт лист wacko.gif

зы.чуть не забыл.
после 56 байт приходит пакет MRIM_CS_USER_STATUS

Пакет: Смена статуса другого пользователя 

Имя пакета: MRIM_CS_USER_STATUS
Тип пакета: sc
Параметры:

UL ## status ## новый статус пользователя ##

STATUS_OFFLINE ## Пользователь отключен от сети Агента
STATUS_ONLINE ## Пользователь находится в сети
STATUS_AWAY ## Пользователь в сети, но отошел от компьютера
STATUS_UNDETERMINATED ## Настройки пользователя запрещают показывать его статус
STATUS_FLAG_INVISIBLE ## Пользователь находится в сети, но невидим для всех, кроме привилегированных пользователей из его списка видимости.
LPS ## user ## email сменившего свой статус пользователя

Описание: Это сообщение отправляется сервером при смене статуса пользователям всем тем, у кого он находится в контакт-листе (за исключением группы "Жду Авторизации" и тех, кого он включил в список игнорируемых или невидящих). Данное сообщение может быть доставлено клиенту ДО получения им контакт-листа. В такой ситуации оно должно игнорироваться.

а как игнорировать?можно впринципе буфер большой выделить и забить все туда сразу biggrin.gif
но кто их знает,че они там еще пришлют,вдруг че пропущу важное.

Автор: Yason 19:04:2008, 22:51

А как полностью выглядит принятое по MRIM_CS_USER_INFO? (ник можно звёздочками)

Автор: ReindeeR 19:04:2008, 23:25

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

Автор: Yason 20:04:2008, 01:03

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).

Автор: ReindeeR 20:04:2008, 01:05

в том то и дело,
указываю меньше 4 кб,
всякая фигня оказывается в строке

Автор: Yason 20:04:2008, 01:32

Фигня, очевидно, показывается из-за того, что C/C++ понимает строки как массивы, завершающиеся нулём, а mail.ru их понимает как (4 байта длины)+(массив указанной длины, без нуля в конце).

Автор: ReindeeR 20:04:2008, 01:42

ну ладно,это не так важно пока что.
что делать с этими пакетами,которые идут как-то не так.
щас попробую до конца все принять,пока не успокоятся))

Автор: ReindeeR 21:04:2008, 14:27

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

Форум Invision Power Board (http://nulled.ws)
© Invision Power Services (http://nulled.ws)