Envío de correos electrónicos mediante C

I have just started learning about socket programming and learned about winsock and achieved some progress. my question is basically: I want to send emails, what should I do?

points to be mentioned:

  1. I learned about initializing winsock. SMTP port (25). creating and connecting to sockets successfully. What should I do now?!!! (I'm stuck here)
  2. I don't want a ready-for-work code. I wanna learn. So, any books, documentations, tutorials or articles recommendations are needed.
  3. I know that C itself knows nothing about networking, does that mean I have to download some libraries? (I am using VS2010, Windows 7)

Here are the links to pages I have read so far:

basic winsock guide: http://msdn.microsoft.com/en-us/library/windows/desktop/ms737629(v=vs.85).aspx

I have read the first 14 pages from beej guide (can't post the link, new users can only post a maximum of two hyperlinks)

I have learned about the types ( WSADATA, addrinfo structure, sockaddr, SOCKET ) and functions ( WSAStartup(), WSACleanup(), getaddrinfo(), Shutdown(), WSAGetLastError(), socket(), ...)

and I have just started reading this article about SMTP http://www.faqs.org/rfcs/rfc821.html

here's what I have written till now:

#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;
}

am I off course?

preguntado el 02 de febrero de 12 a las 10:02

I'd recommend reading Stevens' excellent "TCP/IP Illustrated" book, and also his "Advanced Programming in the Unix Environment". Yes, I know it says Unix, but it's really an excellent book and winsock is basically an implementation of the BSD socket API. -

5 Respuestas

Deberías echar un vistazo a some examples on smtp via telnet :)

Basically you need to input in plaintext something like this:

HELO local.domain.name 
MAIL FROM: mail@domain.ext
RCPT TO: mail@otherdomain.ext
DATA
...

EDITAR de acuerdo a este ejemplo, su código debe ser:

// 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: mail@domain.ext" SEPARATOR);
sendData( socket, "RCPT TO: mail@otherdomain.ext" 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

Respondido 02 Feb 12, 16:02

I did run over something like this, but couldn't understand what to do with that? I mean where to put this text? and why? what does "HELO" mean ( i think saying hello to the server )? - Joker

@joker put it in telnet: en.wikipedia.org/wiki/Telnet there's even a program for that in windows named the same. - Flavius

@joker: 'In the HELO command the host sending the command identifies itself; the command may be interpreted as saying "Hello, I am <domain>"' - cha0site

Don't forget to READ AND PROCESS the server's responses to each command! That is very important. - Remy Lebeau

@Vyktor: thanks a lot for your help and concern your answer with the one above yours, I can now make the program. I can now understand the idea of talking to the server. the problem I'm facing now is how to deal with SSL and TLS ( I'm googling that ) - Joker

You should read how to use smtp over telnet. After that you can easily implement it..

Respondido 02 Feb 12, 14:02

I have read the page u linked to. I learned a few things, but it seems to be outdated. I had to search for the "connect menu" and port to open yahoo mail server ( since 25 is entered, the connection fails ) your help is much appreciated - Joker

I would recommend you this article :

SMTP Client - CodeProject

You can compile it under linux and Windows also.

Respondido 02 Feb 12, 16:02

+1 you can write your own SMTP client, but it's definitely easier to use one of the many that can be found on the Interwebs. - JeremyP

Also you can check source code of open source mail clients like sendmail. - rkosegi

RFC 5321 is the official specification for the basic SMTP protocol.

RFC 2822 is the official specification for the basic email format.

Be aware that there are MANY additional RFCs that extend the basic rules. For instance, RFC 1651 extends SMTP so additional features can then be implemented, such as secure authentication via the AUTH extension. And MIME (RFCs 2045, 2046, 2047, 2048y 2049) is commonly used in modern email systems for allowing attachments, HTML/RTF, etc.

Utilice la herramienta IETF's website to see all available RFC specs used by most Interpet protocols.

Respondido 07 Oct 21, 09:10

bytes_to_receive = sizeof(packet)

received_bytes = 0; do { received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes) } while (received_bytes != bytes_to_receive)

respondido 24 mar '15, 11:03

¿Podría elaborar más su respuesta agregando un poco más de descripción sobre la solución que proporciona? - abarisone

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.