Модераторы: feodorv

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите исправить программу, POP3 
:(
    Опции темы
Edik
Дата 24.9.2007, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



Компилируеться без ошибок, но во время работы при включеном интернете выдает ошибку времени исполнения. Посмотрите пожалуйста кто- нибудь и помогите. А то сам ничего не могу разобраться.
Программа по идее должна выводить количество писем в почтовом ящике.
Код

void CMyPOP3Dlg::OnButton1() 
{
    // TODO: Add your control notification handler code here
    SOCKET m_hSocket;
    int nPort=110;
    char *pszHostAddress;
    char *pszUser;
    char *pszPassword;

    m_server.GetWindowText(pszHostAddress,30);
    m_user.GetWindowText(pszUser,30);
    m_pass.GetWindowText(pszPassword,30);

    m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    SOCKADDR_IN sockAddr;
    ZeroMemory(&sockAddr, sizeof(sockAddr));
    sockAddr.sin_family = AF_INET;
    sockAddr.sin_port = htons((u_short)nPort);
    sockAddr.sin_addr.s_addr = inet_addr(pszHostAddress);

if (sockAddr.sin_addr.s_addr == INADDR_NONE)
    {
        LPHOSTENT lphost;
        lphost = gethostbyname(pszHostAddress);
        if (lphost != NULL)
            sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
        else
        {
            WSASetLastError(WSAEINVAL); 
        }
    }

connect(m_hSocket, (PSOCKADDR)&sockAddr, sizeof(sockAddr));

    char sBuf[30];
    char* pszAsciiUser = (LPTSTR) pszUser;
    sprintf(sBuf, "USER %s\r\n", pszAsciiUser);
    int nCmdLength = strlen(sBuf);

send(m_hSocket, sBuf, nCmdLength, 0);



char* pszAsciiPassword = (LPTSTR) pszPassword;
ASSERT(strlen(pszAsciiPassword) < 100);
sprintf(sBuf, "PASS %s\r\n", pszAsciiPassword);
nCmdLength = strlen(sBuf);
send(m_hSocket, sBuf, nCmdLength, 0);

    
strcpy(sBuf, "STAT\r\n");
nCmdLength = strlen(sBuf);
send(m_hSocket, sBuf, nCmdLength, 0);

char* pszBuf;
int nBuf=strlen(pszBuf);
int nData =recv(m_hSocket, pszBuf, nBuf, 0);

m_result.SetWindowText(pszBuf);

closesocket(m_hSocket);

}


PM MAIL   Вверх
jonie
Дата 24.9.2007, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 5
Всего: 118



Цитата

Код

    char *pszHostAddress;
    char *pszUser;
    char *pszPassword;

    m_server.GetWindowText(pszHostAddress,30);
    m_user.GetWindowText(pszUser,30);
    m_pass.GetWindowText(pszPassword,30);

не выделена память и т.д.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Edik
Дата 25.9.2007, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



Всмысле так надо было написать?

Код

char pszHostAddress[30];
char pszUser[30]
char pszPassword[30];


А все остальное правильно?
PM MAIL   Вверх
ptr
Дата 25.9.2007, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(Edik @  25.9.2007,  13:53 Найти цитируемый пост)
А все остальное правильно?


Цитата(Edik @  24.9.2007,  18:04 Найти цитируемый пост)
но во время работы при включеном интернете выдает ошибку времени исполнения.


Неплохо было бы знать какую ошибку выдает.



--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Edik
Дата 25.9.2007, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



Вот я исправил програму, ошибок уже не выдает, но в поле результата у меня знак "плюс". что это все значит, я не знаю, объсните мне кто нибудь, я в этой теме полный лох. И кстати почему это мне сделали замечание, что не выделена память в предыдущих постах? И правда я исправил это и нету глюков в проге, но результат выдает не тот. Как выделить вобще память, вроде же для символьных оператов типа char * pszUser; использовать new не надо.

Код

void CMyPOP3Dlg::OnButton1() 
{
    // TODO: Add your control notification handler code here

    SOCKET m_hSocket;    //Windows Socket инициализирован в AppWizard
    int nPort=110;
    char pszHostAddress[30];
    char pszUser[30];
    char pszPassword[30];

    m_server.GetWindowText(pszHostAddress,30);
    m_user.GetWindowText(pszUser,30);
    m_pass.GetWindowText(pszPassword,30);

    if((m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))== INVALID_SOCKET )
        AfxMessageBox("Socket Error");

    SOCKADDR_IN sockAddr;
    ZeroMemory(&sockAddr, sizeof(sockAddr));
    sockAddr.sin_family = AF_INET;
    sockAddr.sin_port = htons((u_short)nPort);
    sockAddr.sin_addr.s_addr = inet_addr(pszHostAddress);

if (sockAddr.sin_addr.s_addr == INADDR_NONE)
    {
        LPHOSTENT lphost;
        lphost = gethostbyname(pszHostAddress);
        if (lphost != NULL)
            sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
        else
        {
            WSASetLastError(WSAEINVAL); 
        }
    }

if(connect(m_hSocket, (PSOCKADDR)&sockAddr, sizeof(sockAddr))== INVALID_SOCKET )
    AfxMessageBox("Connect Error");

    char sBuf[30];
    char* pszAsciiUser = (LPTSTR) pszUser;
    sprintf(sBuf, "USER %s\r\n", pszAsciiUser);
    int nCmdLength = strlen(sBuf);

if(send(m_hSocket, sBuf, nCmdLength, 0)== SOCKET_ERROR )
    AfxMessageBox("USER send Error");



    char* pszAsciiPassword = (LPTSTR) pszPassword;
    ASSERT(strlen(pszAsciiPassword) < 100);
    sprintf(sBuf, "PASS %s\r\n", pszAsciiPassword);
    nCmdLength = strlen(sBuf);
if(send(m_hSocket, sBuf, nCmdLength, 0)== SOCKET_ERROR )
    AfxMessageBox("PASS send Error");

    
    strcpy(sBuf, "STAT\r\n");
    nCmdLength = strlen(sBuf);
if( send(m_hSocket, sBuf, nCmdLength, 0)== SOCKET_ERROR)
     AfxMessageBox("STAT send Error");

char pszBuf[30];
int nBuf=strlen(pszBuf);
int nData =recv(m_hSocket, pszBuf, nBuf, 0);

if(nData==0 || nData == SOCKET_ERROR)
    AfxMessageBox("Recv Error");

    m_result.SetWindowText(pszBuf);

    strcpy(sBuf, "QUIT\r\n");
    nCmdLength = strlen(sBuf);
if(send(m_hSocket,sBuf,nCmdLength,0)==SOCKET_ERROR)
AfxMessageBox("QUIT send Error");

closesocket(m_hSocket);

}


PM MAIL   Вверх
ptr
Дата 26.9.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



1. Если сразу не видишь ошибку, то пользуйся отладчиком.
2. 
Код

char pszBuf[30];
int nBuf=strlen(pszBuf);
int nData =recv(m_hSocket, pszBuf, nBuf, 0);

Интересно чему же будет равен nBuf.
3. Почитай про send/recv. Особенно про то, сколько данных они отправляют.
4. На каждую введенную команду сервер шлет ответ. После каждой посланной команды этот ответ стоит проверять.

Это сообщение отредактировал(а) ptr - 26.9.2007, 10:37


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Edik
Дата 26.9.2007, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



я проверял то что ты говоришь, и nBuf показывает реальную длинну строки. я же не пользуюсь sizeof(), я пользуюсь strlen(), вот в чем разница. может кто поможет разобраться с программой? а то я в msdn-е не очень понимаю.
PM MAIL   Вверх
Edik
Дата 27.9.2007, 08:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



я понял, да ты прав, надо указать длинну. я просто не сразу догнал что ты говоришь. я исправил эту ошибку, теперь сервер на команду stat выдает мне ответ такой +OK mPOP POP3 server ready <74. И что это значит? у меня не 74 письма в ящике.
PM MAIL   Вверх
ptr
Дата 27.9.2007, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(Edik @  27.9.2007,  11:41 Найти цитируемый пост)
+OK mPOP POP3 server ready <74

Это приглашение сервер шлет когда ты подключаешься к нему (кстати ты получил неполное приглашение). Если ты ещё раз вызовешь recv то получишь следующую часть. 
Поскольку тебе надо считывать данные до \r\n, то напиши фукнцию которая будет читать из сокета строку.

Прочитай внимательно пункт 3 и 4 в моём предыдущем сообщении. 
По поводу 3 пункта. Recv принимает не все данные, а только ту часть которая на текущий момент пришла. Аналогично и с send.
По поводу 4. После подключения сервер шлет приглашение и после каждой команды (USER, PASS, STAT,...) сервер шлет ответ (удачная команда или нет). Поэтому после каждой команды надо проверять что сервер прислал. 


--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Edik
Дата 27.9.2007, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



Хорошо ptr у меня все получилось, только команды STAT и LIST шлют одинаковые значения- 22 письма. А у меня 22 письма прочитанных в ящике. Не прочитанных 17. То есть всего 39 писем в ящике. Как получить это число 39 а не 22. Мне надо добраться до непрочитанных. Кроме того некоторые сервера вроде mail.ukrpost.ua на в ответ на посылку пароля мне выдают ошибку, хотя пароль правильный. насколько знаю то в зе бате там например для этого почтового сервера надо какуюто дополнительную аутенификацию. как мне получить в этом случае доступ к якщику, пройти эту аутенификацию, так как я говорю, что пароль был правильный, а выдало ошибку когда я послал PASS ошбику -ERR Authentication failed.
PM MAIL   Вверх
Edik
Дата 27.9.2007, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



всмысле, ptr у меня ваще 22 письма в ящике, как показывали STAT и LIST, но как мне получить что 17 писем в ящике новых? или такого в протоколе не предусмотрено? кроме того, когда я получаю письмо командой RETR могу ли я установить, что письмо просмотрено, что оно уже не новое? и объясни мне эту аутенификацию, что я тебе писал в предыдущем посте. все спасибо.
PM MAIL   Вверх
ptr
Дата 27.9.2007, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 661
Регистрация: 31.5.2006
Где: Новосибирск

Репутация: 9
Всего: 14



Цитата(Edik @  27.9.2007,  18:26 Найти цитируемый пост)
но как мне получить что 17 писем в ящике новых?

С помощью POP3 - никак. POP3 обеспечивает только базовый доступ. Для получения информации о новых письмах надо использовать IMAP.

Цитата(Edik @  27.9.2007,  18:26 Найти цитируемый пост)
кроме того, когда я получаю письмо командой RETR могу ли я установить, что письмо просмотрено, что оно уже не новое?

Нет.

Цитата(Edik @  27.9.2007,  18:26 Найти цитируемый пост)
 и объясни мне эту аутенификацию, что я тебе писал в предыдущем посте.

В POP3 можно использовать 3 способа аутентификации:
1. Самый простой и опасный - с помощью команд USER/PASS.
2. Альтернативный метод - командой APOP. Эта команда является опциональной и серверы её не обязаны поддерживать. Если сервер поддерживает APOP, то в приглашении будет выдан ключ (временная метка). Например:
Цитата

+OK <[email protected]>

Или как было у тебя
Цитата

+OK mPOP POP3 server ready <74

Далее эту метку с паролем надо зашифровать MD5:
"<[email protected]>пароль" -> "3251fb5396fa27ebf357baa640416a1c". И уже это значение отсылать: APOP "имя ящика" "MD5 хэш".
3.  Ну и самый продвинутый -  с помощью команды AUTH. В ней надо выбрать механизм аутентификации и по этому механизму уже аутентифицироваться.



--------------------
Единственный способ определить границы возможного - это выйти за эти границы, в невозможное.
Артур Кларк.
PM MAIL ICQ   Вверх
Edik
Дата 28.9.2007, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



так все таки я не пойму чего я не могу зайти на mail.ukrpost.ua? юсера принимает, пароль не принимает- подскажи выход. в чем тут проблема? и где посмотреть подробно по команде AUTH? это что новая команда POP3- потому что в документации- про нее я вроде не видел ничего.
PM MAIL   Вверх
Edik
Дата 29.9.2007, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 207
Регистрация: 13.9.2006

Репутация: нет
Всего: 1



пробовал я AUTH мне выдает -ERR Unsupported authentication mechanism. я просто посылал эту команду. прочитал некоторый хелп (нашел на гугле). вобще то я так понял, что если просто послать AUTH то программа должна хотя бы вернуть что- то вроде того механизма аутенификации, который поддерживаеться? но мне прислало ошибку. потом я еще попробывал послать AUTH KERBEROS_V4, AUTH GSSAPI, AUTH SKEY (это я так понял варианты аутенификации), все равно мне присылает ответ -ERR Unsupported authentication mechanism. а APOP команду я просто посылал, но видимо как ты объяснял (и я еще почитал), ее просто не пошлеш- надо зашифровать ответ сервера по этому шифру MD5. Я правильно понял?
PM MAIL   Вверх
jonie
Дата 29.9.2007, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 5
Всего: 118



сделай банальнее - возьми в руки снифер и погляди как это делают почтовики, что работают с этим сервером 8) всегда помогало...
и вообще стоит почитать rfc...
ну и ЕСТЬ уже готовые библиотеки решающие твою задачу, может стоит довериться им?

и кстати стоит почитать что пишет сам провайдер:
Код

у якості логіна/імені користувача обов’язково вкажіть повне ім'я скриньки включаючи домен (наприклад: «[email protected]»);

я слабо понимаю по украински) но смысл понятен 8)

MD5 это не шифрофункция, это хешфункция.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0584 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.