c语言 发送电子邮件

源码如下, 详情请参考windows网络编程,base64编码,RFC821文档的MIME格式说明,qq的MIME格式请从qq邮箱任意邮件导出eml文件。

以下源码在VC++6.0下编译通过,请在工程->设置->连接->对象库/模块中加入ws2_32.lib 
测试用邮箱为172171882@qq.com,用于名密码已被修改,编译时请用自己的邮箱
要注意,MIME格式要求严格,tab,换行一个都不能少。
#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

//Global Variables Declaration
const char* HostName = "Smtp.qq.com"; //Mail Server
const char* MailData = "From: \"zhao\"<172171882@qq.com>\r\n"
"To: \"zhao\"<172171882@qq.com>\r\n"
"Date: Mon, 25 Oct 2005 14:24:27 +0800\r\n"
"Subject: picture is comming!\r\n\r\n"
"new hello!\r\n.\r\n";

//User-Define Function Declaration
void Usage(void);                       //CopyRight
const char base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; 
char *base64_encode(char* data, int data_len)
{
//int data_len = strlen(data);
int prepare;
int ret_len;
int temp = 0;
char *ret = NULL;
char *f = NULL;
int tmp = 0;
char changed[4];
int i = 0;
ret_len = data_len / 3;
temp = data_len % 3;
if (temp > 0)
{
ret_len += 1;
}
ret = (char *)malloc(ret_len*4 + 1);
if ( ret == NULL)
{
printf("No enough memory.\n");
exit(0);
}
f = ret;
while (tmp < data_len)
{
temp = 0;
prepare = 0;
memset(changed, '\0', 4);
while (temp < 3)
{
//printf("tmp = %d/n", tmp);
if (tmp >= data_len)
{
break;
}
prepare = ((prepare << 8) | (data[tmp] & 0xFF));
tmp++;
temp++;
}
prepare = (prepare<<((3-temp)*8));
//printf("before for : temp = %d, prepare = %d/n", temp, prepare);
for (i = 0; i < 4 ;i++ )
{
if (temp < i)
{
changed[i] = 0x40;
}
else
{
changed[i] = (prepare>>((3-i)*6)) & 0x3F;
}
*f = base[changed[i]];
//printf("%.2X", changed[i]);
f++;
}
}
*f = '\0';
return ret;
}

void SendMsg(SOCKET server, const char *msg)
{
    char Buffer[1024] = {0};
    int ret = 0;
//Send "HELO Server\r\n" to Mail Server
    ret = send(server, msg, strlen(msg), 0);
    if (ret == SOCKET_ERROR)
    {
printf("Send %s to Mail Failure...\n", msg);
goto CleanUP;
    }
    else
    {
printf("%s OK\n", msg);   
    } 
    
    //Recv Data From Mail Server
    ZeroMemory(Buffer, sizeof(Buffer));
    ret = recv(server, Buffer, sizeof(Buffer), 0);
    if (ret == SOCKET_ERROR)
    {
printf("Receive Data From Mail Server Failure...\n");    
goto CleanUP;     
    }
    else
    {
Buffer[ret] = ' ';
printf("%s\n", Buffer);
    }
return ;
CleanUP:
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();                     //Cleanup Winsock
    exit(0);
}
//Mail Function
int SendMain(int argc, char *argv[])
{
    WSADATA wsa;
    struct hostent *pHostent = NULL;
    SOCKET server = INVALID_SOCKET;
    struct sockaddr_in ServerAddr;
    int ret = 0;
    char Buffer[1024] = {0};
char *minedata;
    
    Usage();                                         //Print Copyright
    
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)       //Init Socket
    {
printf("Init Socket Failure...\n");
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();  
exit(0);
    }
    
    server = socket(AF_INET, SOCK_STREAM, 0);        //Create Socket Handle
    if (server == INVALID_SOCKET)
    {
printf("Create Socket Failure...\n");
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();  
exit(0);
    }
    
    pHostent = gethostbyname(HostName);              //Get Mail Server Name
    if (pHostent == NULL)
    {
printf("The Host Name is Invalid...\n");
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();  
exit(0);
    }
    
    //Fill Sockaddr_in Structure
    ServerAddr.sin_family = AF_INET;
    memcpy(&ServerAddr.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);
    ServerAddr.sin_port = htons(25);
    
    //Connect to remote Mail Server
    ret = connect(server, (struct sockaddr*)&ServerAddr, sizeof(ServerAddr));
    if (ret == SOCKET_ERROR)
    {
printf("Connect Mail Server Failed...\n");
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();  
exit(0);
    }
    
    printf("Connect to %s...\n", inet_ntoa(ServerAddr.sin_addr));
    
    //Recv Data From Mail Server
    ZeroMemory(Buffer, sizeof(Buffer));
    ret = recv(server, Buffer, sizeof(Buffer), 0);
    if (ret == SOCKET_ERROR)
    {
printf("Receive Data From Mail Server Failure...\n");    
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();  
exit(0);    
    }
    else
    {
Buffer[ret] = ' ';
printf("%s\n", Buffer);
    }
    
    SendMsg(server, "HELO Server\r\n");
    SendMsg(server, "AUTH LOGIN\r\n");
    SendMsg(server, "MTcyMTcxOdfDgy\r\n");//用户名
    SendMsg(server, "MTM2OTc2NzMsdfwNjU=\r\n");//密码
    SendMsg(server, "MAIL FROM: <172171882@qq.com>\r\n");
    SendMsg(server, "RCPT TO: <172171882@qq.com>\r\n");
    SendMsg(server, "Data\r\n");
////////////////////////////////////////////////////////////////////////////////////////

    FILE* pf = fopen("d:\\pic.jpg","rb");
    fseek(pf,0,SEEK_END);  
    int filelen = ftell(pf);  
    fseek(pf,0,SEEK_SET);  
    char* filebuf = (char*) malloc(filelen);  
    fread(filebuf,1,filelen,pf);  
    char* filebase64 = base64_encode(filebuf,filelen); 

minedata = (char *)malloc(strlen(filebase64)+4096);
ZeroMemory(minedata, strlen(filebase64)+4096);
sprintf(minedata,
"X-QQ-SSF: 0001000000000020000000000000000\r\n"
"X-HAS-ATTACH: no\r\n"
"X-QQ-BUSINESS-ORIGIN: 2\r\n"
"X-Originating-IP: 210.45.11.132\r\n"
"X-QQ-STYLE: \r\n"
"X-QQ-mid: webmail221t1333761329t3697219\r\n"
"From: \"=?gbk?B?srvKtr79?=\" <172171882@qq.com>\r\n"
"To: \"=?gbk?B?ztLX1Ly6tcTTys/k?=\" <172171882@qq.com>\r\n"
"Subject: =?gbk?B?zbzGrA==?=\r\n"
"Mime-Version: 1.0\r\n"
"Content-Type: multipart/mixed;\r\n"
"\tboundary=\"----=_NextPart_4F7F9531_08B02E20_6E086CD1\"\r\n"
"Content-Transfer-Encoding: 8Bit\r\n"
"Date: Sat, 7 Apr 2012 09:15:29 +0800\r\n"
"X-Priority: 3\r\n"
"Message-ID: <tencent_1BEFD3F31DA22E5629F9C688@qq.com>\r\n"
"X-QQ-MIME: TCMime 1.0 by Tencent\r\n"
"X-Mailer: QQMail 2.x\r\n"
"X-QQ-Mailer: QQMail 2.x\r\n\r\n"
"This is a multi-part message in MIME format.\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_6E086CD1\r\n"
"Content-Type: multipart/alternative;\r\n"
"\tboundary=\"----=_NextPart_4F7F9531_08B02E20_212FB248\";\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_212FB248\r\n"
"Content-Type: text/plain;\r\n"
"\tcharset=\"gbk\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_212FB248\r\n"
"Content-Type: text/html;\r\n"
"\tcharset=\"gbk\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"
"PGRpdj48YnI+PC9kaXY+\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_212FB248--\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_6E086CD1\r\n"
"Content-Type: application/octet-stream;\r\n"
"\t charset=\"gbk\";\r\n"
"name=\"pic.jpg\"\r\n"
"Content-Disposition: attachment; filename=\"pic.jpg\"\r\n"
"Content-Transfer-Encoding: base64\r\n\r\n"
"%s\r\n\r\n"
"------=_NextPart_4F7F9531_08B02E20_6E086CD1--\r\n\r\n"
"\r\n.\r\n", filebase64
); 

    SendMsg(server, minedata);
    SendMsg(server, "QUIT\r\n");
if (server != INVALID_SOCKET)
{
closesocket(server);   //Close Socket Handle
}
WSACleanup();                     //Cleanup Winsock
    
    
return 0;
}
//End of Mail Function

//Usage Function Defination, Provider Some help to User
void Usage(void)
{
printf("------------------------------------------------------------\n");
printf("The Demo of Collects data by Sending mail\n");
printf("Codz by Netxfly [E.S.T]\n");
printf("------------------------------------------------------------\n");
return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值