【问题标题】:Sending emails using C使用 C 发送电子邮件
【发布时间】:2012-02-25 00:49:57
【问题描述】:

刚开始学习socket编程,学习了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

我已经阅读了beej指南的前14页(不能发布链接,新用户最多只能发布两个超链接)

我已经了解了类型(WSADATAaddrinfo structuresockaddrSOCKET)和函数(WSAStartup()WSACleanup()getaddrinfo()Shutdown()WSAGetLastError()、@ 987654332@, ...)

我刚刚开始阅读这篇关于SMTPhttp://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;
}

我跑题了吗?

【问题讨论】:

  • 我推荐阅读 Stevens 出色的“TCP/IP 图解”一书,以及他的“Unix 环境中的高级编程”。是的,我知道它说的是 Unix,但这确实是一本很棒的书,winsock 基本上是 BSD 套接字 API 的实现。

标签: c sockets smtp winsock send


【解决方案1】:

你应该看看some examples on smtp via telnet :)

基本上你需要像这样以纯文本形式输入:

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

编辑根据this example,你的代码应该是:

// 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

【讨论】:

  • 我确实遇到过这样的事情,但不明白该怎么办?我的意思是把这段文字放在哪里?为什么? “HELO”是什么意思(我想向服务器问好)?
  • @joker 将其放入 telnet:en.wikipedia.org/wiki/Telnet 在 Windows 中甚至还有一个程序,名称相同。
  • @joker: '在 HELO 命令中,发送命令的主机标识了自己;该命令可能被解释为“你好,我是 ”'
  • 不要忘记阅读和处理服务器对每个命令的响应!这很重要。
  • @Vyktor:非常感谢您的帮助,并关注您对上述问题的回答,我现在可以制作程序了。我现在可以理解与服务器交谈的想法了。我现在面临的问题是如何处理 SSL 和 TLS(我正在谷歌上搜索)
【解决方案2】:

您应该阅读如何在telnet 上使用 smtp。之后,您可以轻松实现它..

【讨论】:

  • 我已阅读您链接到的页面。我学到了一些东西,但它似乎已经过时了。我必须搜索“连接菜单”和端口才能打开雅虎邮件服务器(输入 25,连接失败)非常感谢您的帮助
【解决方案3】:

我会推荐你​​这篇文章:

SMTP Client - CodeProject

linux和windows下也可以编译。

【讨论】:

  • +1 您可以编写自己的 SMTP 客户端,但使用 Internet 上的众多客户端之一肯定更容易。
  • 还可以查看sendmail等开源邮件客户端的源代码。
【解决方案4】:

RFC 5321 是基本 SMTP 协议的官方规范。

RFC 2822 是基本电子邮件格式的官方规范。

请注意,还有许多扩展基本规则的附加 RFC。例如,RFC 1651 扩展了 SMTP,因此可以实现其他功能,例如通过AUTH extension 进行安全身份验证。 MIME(RFC 20452046204720482049)通常用于现代电子邮件系统中,用于允许附件、HTML/RTF 等。

转到IETF's website 查看大多数 Interpet 协议使用的所有可用 RFC 规范。

【讨论】:

    【解决方案5】:
    bytes_to_receive = sizeof(packet)
    

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

    【讨论】:

    • 您能否详细说明您的答案,添加更多关于您提供的解决方案的描述?
    猜你喜欢
    • 2016-04-17
    • 2010-10-01
    • 2014-12-11
    • 2017-08-13
    相关资源
    最近更新 更多