如何通过SMTP发送带有C ++附件的电子邮件?

时间:2010-12-22 09:27:43

标签: c windows

我正在尝试创建一个应用程序,该应用程序将发送带附件的电子邮件。邮件发送工作正常,但我不能附加任何东西。我在网上找到了这个代码。有人可以帮助我,如何附加文件?到目前为止我的代码:

int sendmail( char * smtpserver, char * from, char * to, char * subject, char * msg )
{
int         iProtocolPort        = 0;
char        szSmtpServerName[64] = "";
char        szToAddr[64]         = "";
char        szFromAddr[64]       = "";
char        szBuffer[4096]       = "";
char        szLine[255]          = "";
char        szMsgLine[255]       = "";
SOCKET      hServer;
WSADATA     WSData;
LPHOSTENT   lpHostEntry;
LPSERVENT   lpServEntry;
SOCKADDR_IN SockAddr;

// Load command-line args
lstrcpyA( szSmtpServerName, smtpserver );
lstrcpyA( szToAddr, to );
lstrcpyA( szFromAddr, from );

// Attempt to intialize WinSock (1.1 or later)
if ( WSAStartup( MAKEWORD( VERSION_MAJOR, VERSION_MINOR ), &WSData ) )
{
    printf( "\nCannot find Winsock v%d.%d or later", VERSION_MAJOR, VERSION_MAJOR );
    return 1;
}

// Lookup email server's IP address.
lpHostEntry = gethostbyname( szSmtpServerName );
if ( !lpHostEntry )
{
    printf( "\nCannot find SMTP mail server %s", szSmtpServerName );
    return 1;
}

// Create a TCP/IP socket, no specific protocol
hServer = socket( PF_INET, SOCK_STREAM, 0 );
if ( hServer == INVALID_SOCKET )
{
    printf( "\nCannot open mail server socket!" );
    return 1;
}

// Get the mail service port
lpServEntry = getservbyname( "mail", 0 );

// Use the SMTP default port if no other port is specified
if ( !lpServEntry ) iProtocolPort = htons( IPPORT_SMTP );
else iProtocolPort = lpServEntry->s_port;

// Setup a Socket Address structure
SockAddr.sin_family = AF_INET;
SockAddr.sin_port   = iProtocolPort;
SockAddr.sin_addr   = *( (LPIN_ADDR)*lpHostEntry->h_addr_list );

// Connect the Socket
if ( connect( hServer, ( PSOCKADDR ) &SockAddr, sizeof( SockAddr ) ) )
{
    printf( "\nError connecting to Server socket!" );
    return 1;
}

// Receive initial response from SMTP server
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0), "recv() Reply" );

// Send HELO server.com
sprintf_s( szMsgLine, "HELO %s%s", smtpserver, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() HELO" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() HELO" );

// Send MAIL FROM: <sender@mydomain.com>
sprintf_s( szMsgLine, "MAIL FROM:<%s>%s", from, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() MAIL FROM" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() MAIL FROM" );

char buf[ 128 ], str[ 512 ];
char * pch;

memset( str, 0, sizeof( str ) );

strcpy_s( str, to );

pch = strtok( str, "," );//separate email addresses at ','
while (pch != NULL)
{
    memset( buf, 0, sizeof( buf ) );
    //printf("Buf: %s\n",pch);
    strcpy_s( buf, pch );
    pch = strtok (NULL, ",");

    // Send RCPT TO: <receiver@domain.com>
    sprintf_s( szMsgLine, "RCPT TO:<%s>%s", buf, CRLF );
    Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() RCPT TO" );
    Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() RCPT TO" );
}

// Send DATA
sprintf_s( szMsgLine, "DATA%s", CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() DATA" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() DATA" );

//Send Cc
sprintf_s( szMsgLine, "Cc: %s%s", "test@domain.com",CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() Cc" );

// Send Subject
sprintf_s( szBuffer, "Subject: %s\n", subject );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() Subject" );

//Send From
sprintf_s( szBuffer, "From: %s\n", "BIOS Update" );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() From" );

//Send To
sprintf_s( szBuffer, "To: %s\n\n", to );
Check( send( hServer, szBuffer, strlen( szBuffer ), 0 ), "send() To" );

//Attach
sprintf_s( szMsgLine, "Attachment: %s%s", "d:\\test.txt",CRLF );   //this doesn't work
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() Attachment" );

sprintf_s( szMsgLine, "%s%s", msg, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() message-line" );

// Send blank line and a period
sprintf_s( szMsgLine, "%s.%s", CRLF, CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() end-message" );
Check( recv(  hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() end-message" );

// Send QUIT
sprintf_s( szMsgLine, "QUIT%s", CRLF );
Check( send( hServer, szMsgLine, strlen( szMsgLine ), 0 ), "send() QUIT" );
Check( recv( hServer, szBuffer, sizeof( szBuffer ), 0 ), "recv() QUIT" );

// Report message has been sent
printf( "\nMail sent!" );

// Close server socket and prepare to exit.
closesocket( hServer );

WSACleanup();

return 0;
}

谢谢!

1 个答案:

答案 0 :(得分:2)

我建议你阅读一下SMTP协议。

在过去,内容将是UUENCODED,仅使用UUENCODE标头将其嵌入电子邮件正文中就足够了。我在我的时间里做了很多事情:))

据我所知,现在一切都使用MIME。按照Rup的链接(查看他的评论)或搜索互联网以了解MIME的作用。搜索互联网也应该给你两件事:

  1. 编码附件后MIME的外观示例,以及如何在套接字上发送。
  2. 您可以使用资源(库等)为您编写MIME编码,甚至可以将其推送到套接字。
  3. 您还可以找到SMTP库来处理所有SMTP协议。

    您还需要了解有关套接字的更多信息。您是否真的希望将Attachment: %s%s", "d:\\test.txt",CRLF写入套接字会导致系统打开文件并以某种方式将文件内容流式传输到套接字?

    关于代码的附注:

    为何选择CRLF?所有其他电子邮件标头发送\n以终止一行。这就是所需要的一切。

    在电子邮件标题后发送两个换行符(如“收件人:”标题所示)表示电子邮件标题的结尾。您的“附件:”标题实际上构成了电子邮件正文的第一行。