Trucos de Programacion "C" y "C++" en castellano
Entornos Linux y Windows

Mandar mail desde C

Mandar un mail desde C

Este artículo, no va destinado realmente a enseñar como se mandaría un mail desde C, sino a introducir a la programación TCP/IP (Más que nada, para quitar el miedo), para la programación UDP/IP haré un articulo en en futuro próximo.

Si bien voy a poner un código, este no es realmente adecuado para un programa en la vida real (No esta nada optimizado, y he ignorado muchas reglas de "como se debería hacer un programa", para hacerlo más didactico); Los sistemas operativos suelen tener sus propias api para enviar los mail, desde los programas predeterminados, y solo debe considerarse implementar una función similar a la que expongo en el artículo si se quiere hacer un programa TOTALMENTE independiente de la plataforma (u obiamente, un programa de correo).

Sin embargo, sería facil, a traves de los ejemplos, redactar una clase que sirva en un programa real (Si, una clase, espero que nadie redacte una función para enviar mails en C, debería ser en C++, sobretodo por el mantenimiento, y por las "funciones extra", como son el SMTP AUTH, y los distintos sistemas de encriptación empleados, y la futura implementación de IPv6), faltando solo pequeñas variaciones, alguna de las cuales pondré en futuros artículos.

Diferencias de la programación IP entre las distintas plataformas

La programación que voy a exponer en este artículo, es la relacionada con los sockets, Microsoft proporciona una librería de un nivel más alto, la cual no voy a tratar aqui, pero que tiene su "encanto", pues los servicios básicos de internet ya los tiene implementados.

La primera diferencia, son las cabeceras que hay que incluir en el documento, en windows solo hay que declarar la windows.h, y la winsock.h, mientras que en linux, hay que declarar netdb.h, sys/types.h, sys/socket.h, netinet/in.h, y arpa/inet.h, de manera que en al principio del fichero, nos debería quedar una similar a:

En los proyectos en windows, tiene que añadirese la librería wsock32.lib al proyecto.

La segunda diferencia, es que los programas windows requieren la inicialización de la librería de sockets (Y por lo que he visto, es el fallo más comun en los que comienzan a programar con tecnología Ip... Yo tambien caí en esa "trampa"), para lo cual, hay que emplear la función WSAStartup.

Tan importante es abrir e inicializar como cerrar, por lo que debemos emplear la función WSACleanup al finalizar el programa (O al finalizar la función que utilice el protocolo TCP/IP)

La tercera diferencia es un pequeño fallo en la implementación de una de las funciones por parte de Microsoft, se supone que la función shutdown (Para cerrar las comunicaciones en una conexión TCP/IP), debería cerrar el puerto, pero no lo hace (En windows, en las plataformas *nix que he probado, si que lo hace), por lo que hay que emplear la función closesocket, que no existe en el resto de las plataformas.

Comencemos a programar

Lo primero que deberemos hacer, en una función que reciba una dirección de internet, es resolverla mediante la función gethostbyname (Aunque nos hayan introducido una dirección IP), pues de esa manera, hacemos mucho más independiente el programa. Ya hay escrito un articulo al respecto.

El siguiente paso a ralizar, es crear un socket, con la función socket, que nos devolverá un entero; Este entero será el canal de comunicaciones que emplearemos. A esta función se le pasan tres parametros, el primero es en tipo de dirección (En nuestro caso AF_INET), el segundo es si será una conexión UDP o TCP (SOCK_STREAM en nuestro caso, que es una conexión TCP), y el tercer parámetro es el protocolo que se empleará en la conexión (Depende del primer parametro, en nuestro caso 0), de manera que nos quedaría:

sockfd = socket(AF_INET, SOCK_STREAM, 0);

Si nos devuelve un valor menor que 0, entonces no se ha podido abrir el canal de comunicaciones..

El siguiente paso es rellenar la estructura sockaddr_in, en la que pondremos los datos de la máquina a la que nos conectamos (Ponderemos el puerto, la dirección resuelta obtenida de gethostbyname, que nos conectamos a traves de la red Ip, e inicializaremos el resto a 0). Consultar el ejemplo al final de el artículo.

Y el último paso es la comunicación en si misma. Esta depende del protocolo utilizado. En caso del protocolo SMTP, El cliente manda una línea (Acabada en el caracter de salto de línea), y el servidor responde con otra, salvo qu el cliente haya enviado la instrucción data.

Una vez terminada la comunicación, es MUY importante cerrar las comunicaciones, para lo que emplearemos la función shutdown, en la que le especificaremos el socket a cerrar, y lo que queremos que cierre (En nuestro caso, 2, que es que cierre totalmente el canal)

Resultado final

El resultado final debería ser un codigo similar al siguiente:

 

 

Webmaster

Hiperion Pozuelo, Madrid, ES
Soy una persona sencilla, quizas demasiado seria, que disfruto de la vida.
Actualmente busco pareja.