Помощник
Здравствуйте, гость ( Вход | Регистрация )
|
|
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 и все,а что собственно нужно подключать??,не сказано=( ну я удалил эту строчку за ненадобностью идем далее,сказано,в том же описании,что "После установки 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* и отправлять?или как быть? та же история и при приеме данных. Ну вот,все сказал вроде,что непонятно. Если вы дочитали до конца весь этот бред,и не поленились посмотреть описание протокола,огромнейшая просьба,хоть как-то помочь |
|
Сообщение
#1
|
|
![]() |
|
|
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, в конец добавляется много всяких значков и прочей лабуды, иногда вообще захавает конец строки и всяких значков напехается. Почему,не знаю,вот и спрашиваю. ну а так вроде все по коду понятно остальное. извиняюсь за названия переменных Сообщение отредактировал ReindeeR - 19:04:2008, 23:26 |
|
Сообщение
#31
|
|
|
|
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
|
|
|
|
20:04:2008, 01:05
|
|
Новенький ![]() Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
в том то и дело,
указываю меньше 4 кб, всякая фигня оказывается в строке |
|
Сообщение
#33
|
|
|
|
20:04:2008, 01:32
|
|
Продвинутый ![]() ![]() Группа: Программист Сообщений: 139 Регистрация: 27:02:2004 Пользователь №: 296 Репутация: 6
|
Фигня, очевидно, показывается из-за того, что C/C++ понимает строки как массивы, завершающиеся нулём, а mail.ru их понимает как (4 байта длины)+(массив указанной длины, без нуля в конце).
|
|
Сообщение
#34
|
|
|
|
20:04:2008, 01:42
|
|
Новенький ![]() Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
ну ладно,это не так важно пока что.
что делать с этими пакетами,которые идут как-то не так. щас попробую до конца все принять,пока не успокоятся)) |
|
Сообщение
#35
|
|
|
|
21:04:2008, 14:27
|
|
Новенький ![]() Группа: Новенький Сообщений: 39 Регистрация: 3:04:2008 Пользователь №: 16 361 Репутация: 1
|
Yason
вам памятник надо ставить за истреблении нубства в программировании. спс огромное,дальше надеюсь сам разберусь уж как-нибудь. |
|
Сообщение
#36
|
|
![]() |
|
Текстовая версия | Сейчас: 5:09:2008 - 07:16 |