Помощник
Здравствуйте, гость ( Вход | Регистрация )
|
|
3:04:2008, 12:52
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
Вы уж извините,что так сразу,с такими вопросами тупыми врываюсь)
Решил попрактиковаться в работе с сетью и с сокетами, выбор мой пал на создание примитивного mail.ru агента, консольное приложение,которое может хотя бы могло законнектится к серверу, и пройти авторизацию юзера.Сейчас опишу,как и что делаю. Сначала подключаю winsock.2 и подгружаю библиотеку ws2_32.Lib адрес и порт,по которому коннектится Функцией WSAStartup() подготавливаю для работы winsock2 Создаю сокет, заполняю структуру sockaddr_in далее преобразуем адрес сам коннект Вот отсюда и начинаются все непонятки,что делать,как отсылать и принимать. вот описание протокола ]]>http://agent.mail.ru/protocol.html]]> Все проблемы начались с непонятного инклюда,в файле,который выложен в описании протокола, и все,а что собственно нужно подключать??,не сказано=( ну я удалил эту строчку за ненадобностью идем далее,сказано,в том же описании,что "После установки tcp-соединения клиент обязан сразу послать MRIM_CS_HELLO" Вот и главная проблема.Как отправлять,прнимать,и вообще как их создавать,эти пакеты? По порядку, magic,это мне понятно в файле proto.h есть константа версия протокола,тоже понятно откуда брать Sequence,а вот что это такое,я так и не понял. тип пакета,как я понял,тут и надо указывать MRIM_CS_HELLO Адрес и порт отправителя,тут что указывать? Ладно,допустим я разобрался что и где писать, а как называть пакет? из файла вот тут я окончательно запутался. mrim_packet_header_t это тип структуры,и имя пакета одновременно? компилятор ругается,при попытке отправить пакет, приводить его к типу char* и отправлять?или как быть? та же история и при приеме данных. Ну вот,все сказал вроде,что непонятно. Если вы дочитали до конца весь этот бред,и не поленились посмотреть описание протокола,огромнейшая просьба,хоть как-то помочь |
|
Сообщение
#1
|
|
![]() |
|
|
15:04:2008, 03:08
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
Ничего себе тренировочная задачка!
Судя по всему, MRIM_CS_HELLO, как я понял, нужно прописать в seq. Затем отправляешь этот пакет (по сути, только заголовок, ибо в MRIM_CS_HELLO доп. данные не предполагаются) (да, явно приведя к типу char*) и ждёшь, когда тебе придёт ответ от сервера в виде заголовка (с msg=MRIM_CS_HELLO_ACK) и параметров (структура mrim_connection_params_t. К слову, это только тип структуры, а не имя пакета). Ну и дальше, как там описано. P.S. Протокол этот впервые вижу, так что могу в чём-то заблуждаться. Сообщение отредактировал Yason - 15:04:2008, 03:09 |
|
Сообщение
#2
|
|
|
|
15:04:2008, 12:57
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
не,seq это просто номер команды,в ответе он должен быть таким же,короче это не очень важный параметр))
MRIM_CS_HELLO надо отправлять первым,указывая в msg. отправить у меня получается,а вот в ответ приходит чет непонятное. И потом как мне узнать,что пришло? Если принять пакет с msg=MRIM_CS_HELLO_ACK, то как принять mrim_connection_params_t ? это же две разные структуры,и как мне они придут в одном ответе? короче,как было ничего непонятно,так все и осталось) лан,ща буду мучаться |
|
Сообщение
#3
|
|
|
|
16:04:2008, 01:22
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
ReindeeR
Каждый пакет состоит из заголовка (mrim_packet_header_t) и следующих за ними данных (зависят от команды, для MRIM_CS_HELLO_ACK - mrim_connection_params_t; для некоторых команд, типа MRIM_CS_HELLO - отсутствуют). Размер передаваемых данных нужно указывать в mrim_packet_header_t.dlen. Ну, это, я думаю, и так понятно А ответ можно (и нужно) считывать за несколько приёмов. Сначала заголовок размером sizeof(mrim_packet_header_t), затем по считанному заголовку определяешь, какого типа данные ожидаются, создаёшь буфер соответствующего типа, и считываешь из сокета в него остаток пакета. Как узнать что "вам пакет от сервера" - либо тупо ждать после отправки запроса, либо тоже самое, только умно - в отдельном потоке (thread) с контролем таймаута. |
|
Сообщение
#4
|
|
|
|
16:04:2008, 03:42
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
в ответ приходит какая-то фигня размеров в 19 байтов.
зы.причем один раз ап. mrim_connection_params_t 4 байта, можно попробовать вынять эти 4 байта с начала или конца принятых 19 зы. а как это сделать? Сообщение отредактировал ReindeeR - 16:04:2008, 03:52 |
|
Сообщение
#5
|
|
|
|
16:04:2008, 13:18
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
ReindeeR
Могу поспорить, что эта фигня складывается в циферки типа "194.186.55.27:2041" Цитата Рекомендованный для соединения сервер в любой момент времени можно получить в текстовом формате ip:port по адресу mrim.mail.ru:2042 и mrim.mail.ru:443 Зайди браузером на ]]>http://mrim.mail.ru:2042]]>, и воочию увидишь, что именно ты получаешь P.S. Поздравляю, значит приём-передача уже как-то работают! |
|
Сообщение
#6
|
|
|
|
16:04:2008, 13:42
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
ReindeeR Могу поспорить, что эта фигня складывается в циферки типа "194.186.55.27:2041" Зайди браузером на ]]>http://mrim.mail.ru:2042]]>, и воочию увидишь, что именно ты получаешь P.S. Поздравляю, значит приём-передача уже как-то работают! ааааа я как дятел больше 10 дней пытаюсь достучаться по этому адресу и выпытать ответ. мда..внимательнее читать надо щас буду пробовать коннектиться на получаемый адрес |
|
Сообщение
#7
|
|
|
|
16:04:2008, 22:29
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
Новая проблемка))
не получается установить коннект с сервером. Точнее получается,только не совсем правильно. полученный адрес,по которому нужно соединятся с сервером, находится в переменной IPaddr в формате "194.186.55.17:2041". разделяю их с помощью strtok далее засовываю в структуру sockaddr_in dest_addr ну и соединяюсь connect(my_sock,(SOCKADDR*) &dest_addr,sizeof(dest_addr)); ну и собственно ничего не соединяется. еще при компиляции выскакивает варнинг cast from pointer to integer of different size ругается на строчку,где функция htons() в чем опять проблема?и как собственно ее решить? пока сделал так,посмотрел один из адресов,которые выдаются и объявил константами, #define,не знаю как это правильно называется)) |
|
Сообщение
#8
|
|
|
|
17:04:2008, 01:11
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
|
|
Сообщение
#9
|
|
|
|
17:04:2008, 03:16
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
С портом разобрался))
теперь проблема с приемом данных. цитата из описания. Цитата После установки tcp-соединения клиент обязан сразу послать MRIM_CS_HELLO, дождаться MRIM_CS_HELLO_ACK hello отправляю,а в ответ тишина... собственно сделал вывод,что пакет с MRIM_CS_HELLO у меня отправляется криво,раз ответа нет. делаю так: при попытке принять данные все висит секунд 50,ничего не принимая, а потом "Прием данных завершен." |
|
Сообщение
#10
|
|
|
|
17:04:2008, 12:29
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
По идее, там должны быть IP и порт отправителя (т.е. клиента). Если мне не изменяет склероз, должно быть Далее, учитывая, что "длина данных пакета (без учета заголовка)" И ответ, как мне кажется, было бы логичнее ждать в таком виде:
|
|
Сообщение
#11
|
|
|
|
17:04:2008, 14:46
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
По идее, там должны быть IP и порт отправителя (т.е. клиента). IP указывать не надо,а вот порт оказалось обязательно,просто у кого не спрашивал,все говорили типа устанавливается все в ноль ага,поставил ноль. Далее, учитывая, что "длина данных пакета (без учета заголовка)" packHello.dlen=0; ага,поставил ноль. Ну вот после этих исправлений данные пришли. В размере 48 байтов. 44 байта заголовок,и 4 байта данные,mrim_connection_params_t send(my_sock,(char*)&packHello,bufsize,0); опечатался.все так и есть. И ответ, как мне кажется, было бы логичнее ждать в таком виде: обычно так и принимал,просто экспериментировал ну вот,данные получены,проверил,все правильно,msg==MRIM_CS_HELLO_ACK dlen==4 байта,что и ожидалось. Ну и очередной вопрос,как мне достать эти четыре байта,mrim_connection_params_t.ping_period? Сообщение отредактировал ReindeeR - 17:04:2008, 14:47 |
|
Сообщение
#12
|
|
|
|
17:04:2008, 15:01
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
Так а в чём проблема?
|
|
Сообщение
#13
|
|
|
|
17:04:2008, 15:31
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
не знал,что так можно.
интервал получил,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 понятно,таймер и все. а как в консоли это сделать? |
|
Сообщение
#14
|
|
|
|
17:04:2008, 21:40
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
как мне эти данные присоединть к пакету? Аналогично чтению - в несколько этапов. Сначала отправляешь заголовок, потом длину логина, потом сам логин, потом длину пароля, и т.д. Разумеется, dlen должен быть равен суммарной длине данных (исключая заголовок). как отправлять пакет c MRIM_CS_PING каждые 30 секунд? Либо SetTimer(NULL, 0, 30000, SendPing()), либо создать отдельный поток и в нём В обоих случаях, в реальном приложении нужно синхронизировать отправку, чтобы MRIM_CS_PING не был случайно отправлен между заголовком и данными другого пакета. Сообщение отредактировал Yason - 17:04:2008, 21:43 |
|
Сообщение
#15
|
|
|
|
18:04:2008, 01:28
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
ыыы,авторизировался
щас буду пробовать таймер установить. Потоки=темный лес для меня пока что. зы. как синхронизировать все это,чтобы косяков не было? ап. Таймер использовать не получилось,так как он сразу убивается у меня. Всмысле запускаю таймер,выполняется только первый раз при запуске, а потом программа завершается,и абсолютно пофиг,что там таймер запущен. ну а поток создать у меня тем более не получается. ошибок вылезает хз скока. Мне надо передать в функцию потока сокет и интервал пинга. А если учитывать то,что про потоки я прочитал несколько часов назад, для меня эта задача вообще невыполнимая Сообщение отредактировал ReindeeR - 18:04:2008, 04:08 |
|
Сообщение
#16
|
|
|
|
18:04:2008, 13:56
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
Всмысле запускаю таймер,выполняется только первый раз при запуске, а потом программа завершается,и абсолютно пофиг,что там таймер запущен. Ну, программа и не должна ждать таймер, поэтому её нужно зациклить. А учитывая, что для нормальной работы таймера "you need to dispatch messages in the calling thread" © WinAPI, зациклить программу можно как-нибудь так: как синхронизировать все это,чтобы косяков не было? После вдумчивого чтения хелпа по SetTimer, оказалось, что таймер работает через сообщения в основном потоке, поэтому синхронизировать его не нужно. При многопоточности, конечно, всё не так радужно |
|
Сообщение
#17
|
|
|
|
18:04:2008, 14:41
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
дело в том,что у меня приложение консольное,
цикл обработки сообщений никуда не запехаешь)) |
|
Сообщение
#18
|
|
|
|
18:04:2008, 15:55
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
Ну не знаю, не знаю... Это - работает
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); } } |
|
Сообщение
#19
|
|
|
|
18:04:2008, 18:41
|
|
Новенький Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
ну тогда как передать мне в функцию tick() параметры?))
ап. извиняюсь,как обычно туплю Ну не знаю, не знаю... Это - работает int CALLBACK tick() { cout<<"tick\n"; } на такую функцию компилятор матерился. пришлось городить вот так новая проблема. при отсылке такого пакета сразу же обрывается соединение. Сообщение отредактировал ReindeeR - 18:04:2008, 18:09 |
|
Сообщение
#20
|
|
|
|
18:04:2008, 21:47
|
|
Продвинутый Группа: Программист Сообщений: 154 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
А ноль ли?.. |
|
Сообщение
#21
|
|