注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

简单代码

寻找代码的灵魂

 
 
 

日志

 
 
关于我

对于本博客内所有原创文章和代码的引用必须标明“来源:http://simplesource.blog.163.com/”。如需应用于商业目的必须经本人同意,本人对所有原创文章和代码保留一切权利。 PS:需要部分程序源代码的请留下邮箱地址

网易考拉推荐

SMTP邮件发送程序  

2015-01-30 16:52:59|  分类: 我的程序 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  纯c写的SMTP邮件发送程序,Suse Linux下编译通过(windows下的socket编写方式以及头文件略有不同)。支持收件人列表发送(收件人之间用“,”号分割),支持发送多个附件,只需在邮件正文中插入“<file:文件路径>”代码程序自动读取并发送附件。注意:程序中未做发件人验证,适合不需要验证发件人的SMTP服务。

  SendMail.h源代码如下(代码中并未给出main函数,请自行添加):

#ifndef SendMail_h_SimpleSource_201502
#define SendMail_h_SimpleSource_201502

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#ifndef SOCKET
#define SOCKET int
#endif
#ifndef SOCKADDR_IN
#define SOCKADDR_IN struct sockaddr_in
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (-1)
#endif
#ifndef SOCKET_ERROR
#define SOCKET_ERROR (-1)
#endif

char cSMEcho = 0;

/*****************************************************************/
/* 功能说明:取得文件大小 */
/* 输入参数:szFilePath [in]文件路径 */
/* 返回:文件的大小,出错返回-1 */
/*****************************************************************/
long SMFileSize(const char * szFilePath)
{
struct stat buf;
if(stat(szFilePath, &buf) != 0)
{
return -1;
}
return buf.st_size;
}
/*****************************************************************/
/* 功能说明:接收socket消息 */
/* 输入参数:hSocket [in]socket句柄 */
/* pBuffer [in]缓冲区指针 */
/* iMaxLen [in]缓冲区大小 */
/* 返回:成功返回接收的长度,出错返回-1 */
/*****************************************************************/
int SMRecv(SOCKET hSocket, char *pBuffer, int iMaxLen)
{
int iLen = recv(hSocket, pBuffer, iMaxLen, 0);
if(iLen == SOCKET_ERROR || iLen == 0)
{
return -1;
}
if(cSMEcho)
{
printf(">>%s", pBuffer);
}
return iLen;
}
/*****************************************************************/
/* 功能说明:发送socket消息 */
/* 输入参数:hSocket [in]socket句柄 */
/* pData [in]需要发送的数据指针 */
/* iLen [in]发送的数据长度, */
/* 如果为0则会自动计算pData的字符串长度 */
/* 返回:成功返回0,出错返回-1 */
/*****************************************************************/
int SMSend(SOCKET hSocket, const char *pData, int iLen)
{
int l;
char *pTmp = (char *)pData;
if(iLen == 0)
{
iLen = strlen(pTmp);
}
if(cSMEcho)
{
printf("%.*s", iLen, pData);
}
while(iLen > 0)
{
l = send(hSocket, pTmp, iLen, 0);
if(l == SOCKET_ERROR || l == 0)
{
return -1;
}
iLen -= l;
pTmp += l;
}
return 0;
}
/*****************************************************************/
/* 功能说明:将文件进行Base64编码后发送 */
/* 输入参数:hSocket [in]socket句柄 */
/* szFilePath [in]文件路径 */
/* 返回:成功返回0,出错返回非零 */
/*****************************************************************/
static int SMSendBase64File(SOCKET hSocket, char *szFilePath)
{
/* 编码表 */
const char *szEncodeTable=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char pData[600];
char szBuffer[1024];
int i, j, l, lLine, iLen;
FILE *fp;
lLine = 0;
fp = fopen(szFilePath, "rb");
if(fp)
{
while(!feof(fp))
{
memset(pData, 0, sizeof(pData));
iLen = fread(pData, 1, 600, fp);
if(iLen <= 0)
{
break;
}
l = iLen - 3;
memset(szBuffer, 0, sizeof(szBuffer));
j = 0;
for(i = 0; i <= l; i += 3)
{
szBuffer[j++] = szEncodeTable[pData[i] >> 2];
szBuffer[j++] = szEncodeTable[((pData[i] << 4)
| (pData[i + 1] >> 4)) & 0x3F];
szBuffer[j++] = szEncodeTable[((pData[i + 1] << 2)
| (pData[i + 2] >> 6)) & 0x3F];
szBuffer[j++] = szEncodeTable[pData[i + 2] & 0x3F];
lLine += 4;
if(lLine == 76)
{
szBuffer[j++] = '\r';
szBuffer[j++] = '\n';
lLine = 0;
}
}
iLen -= i;
if(0 != SMSend(hSocket, szBuffer, j))
{
return -1;
}
/* 对剩余数据进行编码 */
if(iLen != 0)
{
memset(szBuffer, 0, sizeof(szBuffer));
if(iLen == 1)
{
szBuffer[0] = szEncodeTable[(pData[i] & 0xFC) >> 2];
szBuffer[1] = szEncodeTable[((pData[i] & 0x03) << 4)];
szBuffer[2] = '=';
szBuffer[3] = '=';
}
else if(iLen == 2)
{
szBuffer[0] = szEncodeTable[(pData[i] & 0xFC) >> 2];
szBuffer[1] = szEncodeTable[((pData[i] & 0x03) << 4)
| ((pData[i + 1] & 0xF0) >> 4)];
szBuffer[2] = szEncodeTable[((pData[i + 1] & 0x0F) << 2)];
szBuffer[3] = '=';
}
if(0 != SMSend(hSocket, szBuffer, j))
{
return -1;
}
break;
}
}
fclose(fp);
}
else
{
return -2;
}
return 0;
}
/*****************************************************************/
/* 功能说明:发送邮件 */
/* 输入参数:szServer [in]服务器ip */
/* szMailFrom [in]发件人 */
/* szMailTo [in]收件人 */
/* szSubject [in]邮件标题 */
/* szContent [in]邮件内容 */
/* szOutMsg [out]返回信息 */
/* 返回:成功返回0,出错返回其他 */
/*****************************************************************/
int SendMail(
const char *szServer,
const char *szMailFrom,
const char *szMailTo,
const char *szSubject,
const char *szContent,
char *szOutMsg)
{
/* 数据缓冲区 */
char pBuffer[256];
/* 文件路径 */
char szFilePath[256];
/* 分隔符 */
char szBoundary[50];
/* 过渡指针 */
char *p0, *p1, *p2, *p3;
/* socket句柄 */
SOCKET hSocket = INVALID_SOCKET;
/* 接入地址 */
SOCKADDR_IN addr;
/* 收件人名字缓冲区 */
char *pNames = 0;
/* 长度 */
int l;

/* 创建socket */
hSocket = socket( AF_INET ,SOCK_STREAM , IPPROTO_TCP);
if(hSocket == INVALID_SOCKET)
{
strcpy(szOutMsg, "创建socket出错!");
return -2;
}

/* 连接服务器 */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(szServer);
addr.sin_port = htons(25);
if(SOCKET_ERROR ==
connect(hSocket, (struct sockaddr *)&addr, sizeof(addr)))
{
strcpy(szOutMsg, "连接到服务器出错!");
return -3;
}
/* 接收欢迎信息 */
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收欢迎信息出错!");
return -4;
}
if(memcmp(pBuffer, "220", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
return -5;
}
/* 发送HELO */
if(SMSend(hSocket, "HELO LLIKZ\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送HELO出错!");
return -6;
}
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收响应出错!");
return -7;
}
if(memcmp(pBuffer, "250", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
return -8;
}
/*发送mail from命令 */
memset(pBuffer, 0, sizeof(pBuffer));
sprintf(pBuffer, "MAIL FROM:<%s>\r\n", szMailFrom);
if(SMSend(hSocket, pBuffer, 0) != 0)
{
strcpy(szOutMsg, "发送MAIL FROM命令出错!");
return -9;
}
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收响应出错!");
return -10;
}
if(memcmp(pBuffer, "250", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
return -11;
}
/* 发送RCPT TO指令 */
l = strlen(szMailTo);
pNames = malloc(l + 1);
memset(pNames, 0, l + 1);
p0 = (char *)szMailTo;
while(1)
{
while(*p0 == ' ' || *p0 == '\t')
{
p0++;
}
p1 = (char *)strchr(p0, ',');
if(p1 <= p0)
{
p1 = p0 + strlen(p0);
}
if(p1 > p0)
{
p2 = (char *)strchr(p0, ':');
if(*pNames)
{
strcat(pNames, ",");
}
if(p2 > p0 && p2 < p1)
{
strncat(pNames, p0, p2 - p0);
p0 = p2 + 1;
while(*p0 == ' ' || *p0 == '\t')
{
p0++;
}
}
else
{
strncat(pNames, p0, p1 - p0);
}
memset(pBuffer, 0, sizeof(pBuffer));
strcpy(pBuffer, "RCPT TO:<");
strncat(pBuffer, p0, p1 - p0);
strcat(pBuffer, ">\r\n");
if(SMSend(hSocket, pBuffer, 0) != 0)
{
strcpy(szOutMsg, "发送RCPT TO命令出错!");
return -12;
}
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收响应出错!");
return -13;
}
if(memcmp(pBuffer, "250", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
return -14;
}
}
if(*p1 == 0)
{
break;
}
p0 = p1 + 1;
}
/* 发送DATA指令 */
if(SMSend(hSocket, "DATA\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送DATA命令出错!");
if(pNames)
{
free(pNames);
pNames = 0;
}
return -15;
}
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收响应出错!");
if(pNames)
{
free(pNames);
pNames = 0;
}
return -16;
}
if(memcmp(pBuffer, "354", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
if(pNames)
{
free(pNames);
pNames = 0;
}
return -17;
}
/* 生成分隔符 */
sprintf(szBoundary, "bdSendMail201501%d", time(0));
/* 发送邮件数据 */
if( SMSend(hSocket, "From:", 0) != 0
|| SMSend(hSocket, szMailFrom, 0) != 0
|| SMSend(hSocket, "\r\nTo:", 0) != 0
|| SMSend(hSocket, pNames, 0) != 0
|| SMSend(hSocket, "\r\nSubject:", 0) != 0
|| SMSend(hSocket, szSubject, 0) != 0
|| SMSend(hSocket, "\r\nMIME-Version: 1.0", 0) != 0
|| SMSend(hSocket, "\r\nContent-Type: multipart/mixed;", 0) != 0
|| SMSend(hSocket, " boundary=", 0) != 0
|| SMSend(hSocket, szBoundary, 0) != 0
|| SMSend(hSocket, "\r\nContent-Transfer-Encoding: 7bit", 0) != 0
|| SMSend(hSocket, "\r\n\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送邮件数据出错!");
if(pNames)
{
free(pNames);
pNames = 0;
}
return -18;
}
if(pNames)
{
free(pNames);
pNames = 0;
}
p0 = (char *)szContent;
while(*p0 != 0)
{
p1 = (char *)strstr(p0, "<file:");
if(p1 < p0)
{
p1 = p0 + strlen(p0);
}
if(p1 > p0)
{
if( SMSend(hSocket, "--", 0) != 0
|| SMSend(hSocket, szBoundary, 0) != 0
|| SMSend(hSocket, "\r\nContent-Type: text/html;", 0) != 0
|| SMSend(hSocket, "\r\nContent-Transfer-Encoding: 7bit", 0) != 0
|| SMSend(hSocket, "\r\n\r\n", 0) != 0
|| SMSend(hSocket, p0, p1 - p0) != 0
|| SMSend(hSocket, "\r\n\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送邮件数据出错!");
return -18;
}
}
if(*p1 == 0)
{
break;
}
if(*p1 == '<')
{
p0 = p1 + 6;
p1 = (char *)strchr(p0, '>');
if(p1 < p0)
{
break;
}
memset(szFilePath, 0, sizeof(szFilePath));
strncpy(szFilePath, p0, p1 - p0);
p2 = (char *)strrchr(szFilePath, '\\');
p3 = (char *)strrchr(szFilePath, '/');
printf("%d,%d\n", p2, p3);
if(p2 < p3)
{
p2 = p3;
}
if(p2 <= (char *)0)
{
p2 = szFilePath;
}
else
{
p2++;
}
if( SMSend(hSocket, "--", 0) != 0
|| SMSend(hSocket, szBoundary, 0) != 0
|| SMSend(hSocket,
"\r\nContent-Type: application/octet-stream", 0) != 0
|| SMSend(hSocket, "; name=\"", 0) != 0
|| SMSend(hSocket, p2, 0) != 0
|| SMSend(hSocket,
"\"\r\nContent-Description: attachment;", 0) != 0
|| SMSend(hSocket, " filename=\"", 0) != 0
|| SMSend(hSocket, p2, 0) != 0
|| SMSend(hSocket,
"\"\r\nContent-Transfer-Encoding: base64", 0) != 0
|| SMSend(hSocket, "\r\n\r\n", 0) != 0
|| SMSendBase64File(hSocket, szFilePath) != 0
|| SMSend(hSocket, "\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送邮件数据出错!");
return -18;
}
}
p0 = p1 + 1;
}
if( SMSend(hSocket, "--", 0) != 0
|| SMSend(hSocket, szBoundary, 0) != 0
|| SMSend(hSocket, "--\r\n.\r\n", 0) != 0)
{
strcpy(szOutMsg, "发送邮件数据出错!");
return -18;
}
memset(pBuffer, 0, sizeof(pBuffer));
if(SMRecv(hSocket, pBuffer, 255) <= 0)
{
strcpy(szOutMsg, "接收响应出错!");
return -19;
}
if(memcmp(pBuffer, "250", 3) != 0)
{
strcpy(szOutMsg, pBuffer);
return -20;
}
/* 退出登陆 */
SMSend(hSocket, "QUIT\r\n", 0);
strcpy(szOutMsg, "邮件发送成功");
shutdown(hSocket, 2);
close(hSocket);
hSocket = INVALID_SOCKET;
return 0;
}
#endif


  评论这张
 
阅读(1307)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018