Отправка писем с помощью C

Я только начал изучать программирование сокетов, узнал о winsock и добился определенного прогресса. мой вопрос в основном: я хочу отправлять электронные письма, что мне делать?

пункты, которые следует упомянуть:

  1. Я узнал об инициализации winsock. SMTP-порт (25). успешное создание и подключение к сокетам. Что мне теперь делать?!!! (Я застрял здесь)
  2. Мне не нужен готовый к работе код. Я хочу учиться. Таким образом, любые книги, документация, учебные пособия или статьи необходимы.
  3. Я знаю, что сам C ничего не знает о сети, значит ли это, что мне нужно загрузить какие-то библиотеки? (Я использую VS2010, Windows 7)

Вот ссылки на страницы, которые я прочитал до сих пор:

основное руководство по winsock: http://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx

Я прочитал первые 14 страниц руководства beej (не могу опубликовать ссылку, новые пользователи могут публиковать не более двух гиперссылок)

Я узнал о типах ( WSADATA, addrinfo structure, sockaddr, SOCKET ) и функциях ( WSAStartup(), WSACleanup(), getaddrinfo(), Shutdown(), WSAGetLastError(), socket(), ...)

и я только начал читать эту статью о SMTP http://www.faqs.org/rfcs/rfc821.html

вот что я написал до сих пор:

#include <stdio.h>
#include <WinSock2.h>
#include <WS2tcpip.h>

#pragma comment(lib, "Ws2_32.lib") // Applications that use Winsock must be linked with the Ws2_32.lib library file.

#define HTTP_PORT "80"
#define SMTP_PORT "25"
#define HOSTNAME_PORT "101"

/*
All ports and web services names ( which are string aliases of the ports

 can be found here:
 %WINDIR%\system32\drivers\etc\services

 */

int main(void)
{
    WSADATA wsdata;
    int iresult, retval; //iresult : instant result
    SOCKET connect_socket;
    struct addrinfo *result, *ptr, hints;

    iresult = WSAStartup(MAKEWORD(2, 2), &wsdata);
    if(iresult != 0) printf("Initiation of Winsock succeeded.\n");
    else
    {
        printf("WinSock initialization failed..\n");
        WSACleanup();
        return 0;
    }

    if(LOBYTE(wsdata.wVersion) == 2 && HIBYTE(wsdata.wVersion) == 2) printf("winsock.dll is found.\n");
    else
    {
        printf("Can not find the required winsock.dll file.\n");
        WSACleanup();
        return 0;
    }

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
    hints.ai_protocol = IPPROTO_TCP; // TCP connection ( full duplex )
    hints.ai_socktype = SOCK_STREAM; // Provides sequenced, reliable, two-way, connection-based byte streams

    connect_socket = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol);
    if(connect_socket == INVALID_SOCKET)
    {
        printf("Socket Creation failed..\n");
        WSACleanup();
        return 0;
    }
    else printf("Socket Creation Succeeded ..\n");
    WSACleanup();
    return 1;
}

я сбился с курса?


person joker    schedule 02.02.2012    source источник
comment
Я бы порекомендовал прочитать прекрасную иллюстрированную книгу Стивенса TCP/IP, а также его книгу Advanced Programming in the Unix Environment. Да, я знаю, что там написано Unix, но это действительно отличная книга, и winsock в основном является реализацией API сокетов BSD.   -  person cha0site    schedule 02.02.2012


Ответы (5)


Вы должны взглянуть на некоторые примеры smtp через telnet :)

В основном вам нужно ввести в виде открытого текста что-то вроде этого:

HELO local.domain.name 
MAIL FROM: [email protected]
RCPT TO: [email protected]
DATA
...

ИЗМЕНИТЬ согласно этот пример, ваш код должен быть:

// Not sure about this one, maybe just "\n"
#define  SEPARATOR "\n\r"

int sendData( Socket *socket, const char *data) {
    int iResult;
    iResult = send(socket, data, (int) strlen(data), 0);
    if(iResult == SOCKET_ERROR){
      // Do error handling as you like
    }
    return iResult;
}

sendData( socket, "HELO local.doman.name" SEPARATOR);
sendData( socket, "MAIL FROM: [email protected]" SEPARATOR);
sendData( socket, "RCPT TO: [email protected]" SEPARATOR);
sendData( socket, "DATA" SEPARATOR);
sendData( socket, "This is subject of my mail" SEPARATOR SEPARATOR);
sendData( socket, "And this is text" SEPARATOR);
sendData( socket, "." SEPARATOR); // Send mail
person Vyktor    schedule 02.02.2012
comment
Я наткнулся на что-то подобное, но не мог понять, что с этим делать? Я имею в виду, где разместить этот текст? и почему? что означает HELO (я думаю, привет серверу)? - person joker; 02.02.2012
comment
@joker добавил это в телнет: en.wikipedia.org/wiki/Telnet есть даже программа для того, чтобы в окнах назвали то же самое. - person Flavius; 02.02.2012
comment
@joker: «В команде HELO хост, отправляющий команду, идентифицирует себя; команда может быть интерпретирована как «Привет, я ‹домен›». - person cha0site; 02.02.2012
comment
Не забывайте ПРОЧИТАТЬ И ОБРАБОТАТЬ ответы сервера на каждую команду! Это очень важно. - person Remy Lebeau; 03.02.2012
comment
@Vyktor: большое спасибо за вашу помощь и сравните ваш ответ с ответом выше вашего, теперь я могу сделать программу. Теперь я могу понять идею общения с сервером. проблема, с которой я столкнулся сейчас, заключается в том, как работать с SSL и TLS (я это гуглю) - person joker; 03.02.2012
comment
Я задокументирую то, что понял до сих пор, чтобы любой, кто ищет ту же тему, мог легко найти ответ. Я не знаю, где разместить предыдущее предложение, поэтому любой, кто увидит эту тему, может увидеть ссылку на документ. - person joker; 03.02.2012

Вы должны прочитать, как использовать smtp через telnet. После этого вы можете легко реализовать это.

person duedl0r    schedule 02.02.2012
comment
Я прочитал страницу, на которую вы ссылаетесь. Я узнал несколько вещей, но они, кажется, устарели. Мне пришлось искать меню подключения и порт, чтобы открыть почтовый сервер Yahoo (поскольку введено 25, соединение не установлено), ваша помощь очень ценится - person joker; 02.02.2012

Я бы порекомендовал вам эту статью:

Клиент SMTP — CodeProject

Вы также можете скомпилировать его под Linux и Windows.

person rkosegi    schedule 02.02.2012
comment
+1 вы можете написать свой собственный SMTP-клиент, но определенно проще использовать один из многих, которые можно найти в Интернете. - person JeremyP; 02.02.2012
comment
Также вы можете проверить исходный код почтовых клиентов с открытым исходным кодом, таких как sendmail. - person rkosegi; 02.02.2012

RFC 5321 — это официальная спецификация базового протокола SMTP.

RFC 2822 — это официальная спецификация основного формата электронной почты.

Имейте в виду, что существует МНОГИЕ дополнительные RFC, расширяющие базовые правила. Например, RFC 1651 расширяет возможности SMTP, поэтому могут быть реализованы дополнительные функции, такие как безопасная аутентификация через расширение AUTH. И MIME (RFC 2045, 2046, 2047, 2048 и 2049) обычно используется в современных почтовых системах для разрешения вложений, HTML/RTF и т. д.

Перейдите на веб-сайт IETF, чтобы просмотреть все доступные спецификации RFC, используемые большинством протоколов Interpet.

person Remy Lebeau    schedule 02.02.2012

bytes_to_receive = sizeof(packet)

полученные_байты = 0; do { полученные_байты += получено (буфер + полученные_байты, байты_для_получения - полученные_байты) } в то время как (полученные_байты != байты_для_получения)

person ddd    schedule 24.03.2015
comment
Не могли бы вы уточнить свой ответ, добавив немного больше описания решения, которое вы предоставляете? - person abarisone; 24.03.2015