На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Oleg2004
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
    > Winsock. SMTP connection
      Всем привет. Недавно начал разбираться с сокетами, написал пару простых программ для обмена данными по локальной сети. Сейчас захотел попробовать подключиться к smtp-серверу для отправки email письма и возникли некоторые сложности, решения которых я не нашел в google.
      ExpandedWrap disabled
        DWORD SendMessage(const char * email, const char * msg, const char * from)
        {
                WSADATA _wsa;
                WSAStartup(MAKEWORD(2,2), &_wsa);
                hostent * h;
            int handle = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
            if(handle <= 0)
                printf("Error with creation socket %i", GetLastError());
         
            char * em = getSMTPServer(email);
            h = gethostbyname(em);
            delete em;
            if(h == NULL)
            {
                printf("ERROR WITH GETTING HOSTBYNAME - %i\n", GetLastError());
                closesocket(handle);
                return EXIT_FAILURE;
            }
            sockaddr_in destination;
            destination.sin_family = AF_INET;
            destination.sin_port = htons(25);
            destination.sin_addr.s_addr = *((unsigned long *) h->h_addr);
            if(connect(handle,(const sockaddr *)&destination, sizeof(sockaddr_in) == SOCKET_ERROR))
            {
                printf("ERROR WITH CONNECT SMTP-SERVER - %i\n", GetLastError());
                closesocket(handle);
                return EXIT_FAILURE;
            }
         
                ...
         
               WSACleanup();
        }


      Функция getSMTPServer() самописная и возвращает smtp-сервер, основываясь на email-адресе.
      После вызова функции connect() возвращается SOCKET_ERROR и GetLastError() == 10014
        Тебе интересно чисто разобраться?

        Есть два момента, я не знаю с кем ты хочешь связать по 25 порту, но это обычный SMTP вроде и многие так уже не работают, а только с SSL ну и другим портом. И еще если ты пользуешься например gmail или еще кем не своим, полезь в настройки почты и сделай доступным для внешних программ.
          Цитата linuxoid @
          После вызова функции connect() возвращается SOCKET_ERROR и GetLastError() == 10014

          А что означает эта ошибка, ты посмотрел ?
          Попробуй так:
          ExpandedWrap disabled
              
            ..
            if(connect(handle,(const sockaddr *)&destination, sizeof(destination) == SOCKET_ERROR))
            ..

          connect, пример
          Исходники sources.ru
          Сообщение отредактировано: ЫукпШ -
          Подпись была выключена в связи с наложенным заземлением.
            Цитата ter_nk_ @
            Тебе интересно чисто разобраться?

            Есть два момента, я не знаю с кем ты хочешь связать по 25 порту, но это обычный SMTP вроде и многие так уже не работают, а только с SSL ну и другим портом. И еще если ты пользуешься например gmail или еще кем не своим, полезь в настройки почты и сделай доступным для внешних программ.

            не просто разобраться, а сделать так, чтобы письмо все-таки отправилось куда нужно. Наткнулся на статью, в которой говорилось что smtp использует 25 порт, вот я и пробую, возможно, это и правда уже неактуально и следует пробовать другой порт. Но если я буду использовать порт с ssl тогда мне нужно использовать шифрование. Я хотел написать на чистом С, без подключения сторонних библиотек.
              Вполне возможно что самописная функция неверно формирует аргумент для gethostbyname()
              Проверьте - поле h_addr структуры hostent
              Скажем распечатайте.
              GOD IS GOOD! IN ALL THE TIME!
                Цитата linuxoid @
                не просто разобраться, а сделать так, чтобы письмо все-таки отправилось куда нужно. Наткнулся на статью, в которой говорилось что smtp использует 25 порт, вот я и пробую, возможно, это и правда уже неактуально и следует пробовать другой порт. Но если я буду использовать порт с ssl тогда мне нужно использовать шифрование. Я хотел написать на чистом С, без подключения сторонних библиотек.


                А ты пробовал смотреть не статью, а конкретные настройки сервера, они могут убирать такие дыры безопасности, кто сейчас 25 порт использует?
                  Цитата ter_nk_ @
                  А ты пробовал смотреть не статью, а конкретные настройки сервера, они могут убирать такие дыры безопасности, кто сейчас 25 порт использует?

                  я попробовал.
                  Можно законнектится на smtp.mail.ru:25.
                  С операцией "connect" нет проблем.
                  Подпись была выключена в связи с наложенным заземлением.
                    Цитата ЫукпШ @
                    я попробовал.
                    Можно законнектится на smtp.mail.ru:25.
                    С операцией "connect" нет проблем.


                    С gmail это не пройдет.
                      Согласен, что почтовик может и требовать аутентификации, и совсем на другой порт и прочая.
                      Но в любом случае коннект все равно проходил бы, если связка Ip:port была бы реальной. А тут сам коннект не проходит - т.е. первый SYN не находит адресат...
                      GOD IS GOOD! IN ALL THE TIME!
                        Цитата ter_nk_ @
                        Цитата ЫукпШ @
                        я попробовал.
                        Можно законнектится на smtp.mail.ru:25.
                        С операцией "connect" нет проблем.


                        С gmail это не пройдет.

                        Предлагаешь все сервера проверять ?
                        user posted image
                        Подпись была выключена в связи с наложенным заземлением.
                          Извините не знал. У них в настройках для клиента указан только порт с SSL, да я думал на хрена типа оставлять обычный.
                            Именно поэтому я считаю что засада в формировании адреса почтовика...
                            GOD IS GOOD! IN ALL THE TIME!
                              Доброго всем дня. Не был дома несколько дней, не мог отвечать вам на форуме. По поводу ваших доводов о неправильной работе getSMTPServer(const char * email);
                              Возвращаемое значение функцией перед инициализацией gethostbyname();
                              Прикреплённая картинка
                              Прикреплённая картинка

                              структура hostent после инициализации:
                              Прикреплённая картинка
                              Прикреплённая картинка

                              Кажется, что все в порядке с этим
                                И тем не менее для коннекта эта ошибка обозначает неверно сформированный адрес назначения.
                                У меня вызывает подозрение приведение типа
                                destination.sin_addr.s_addr = *((unsigned long *) h->h_addr);
                                Такая запись характерна для связывания локального сокета для BIND на сервере.
                                Попробуйте привести к типу struct in_addr таким образом
                                destination.sin_addr = * ((struct in_addr *) h-> h_addr);
                                И еще проверка - просто возьмите значение возвращенное значение h_addr и посмотрите - получается ли IP-адрес назначения. Адрес идет уже в сетевом порядке.
                                GOD IS GOOD! IN ALL THE TIME!
                                  Цитата Oleg2004 @
                                  И тем не менее для коннекта эта ошибка обозначает неверно сформированный адрес назначения.
                                  У меня вызывает подозрение приведение типа
                                  destination.sin_addr.s_addr = *((unsigned long *) h->h_addr);
                                  Такая запись характерна для связывания локального сокета для BIND на сервере.
                                  Попробуйте привести к типу struct in_addr таким образом
                                  destination.sin_addr = * ((struct in_addr *) h-> h_addr);
                                  И еще проверка - просто возьмите значение возвращенное значение h_addr и посмотрите - получается ли IP-адрес назначения. Адрес идет уже в сетевом порядке.

                                  Попробовал изменить преобразование типов как указали Вы, но результата это особого не дало. Структура sin_addr заполнилась тем же самым IP-адресом, с которым я и пытался установить соединение.
                                  [attach=#0][/attach]

                                  Кстати, попробовал вывести на консоль значение h->h_addr;
                                  Результат следующий:
                                  [attach=#1][/attach]

                                  Возможно, в этом и таится проблема? или такое значение это норма?
                                  Сообщение отредактировано: linuxoid -

                                  Прикреплённая картинка
                                  Прикреплённая картинка

                                  Прикреплённая картинка
                                  Прикреплённая картинка
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script Execution time: 0,2465 ]   [ 22 queries used ]   [ Generated: 14.10.19, 18:58 GMT ]