C语言实现简单的SMTP发送邮件
#include <windows.h>
#include <stdio.h>
#include <WinSock.h>
#include <iostream>
using namespace std
#pragma comment(lib, "ws2_32.lib")
struct Base64Date6
{
unsigned int d4:6
unsigned int d3:6
unsigned int d2:6
unsigned int d1:6
}
// 协议中加密部分使用的是base64方法
char ConvertToBase64 (char c6)
void EncodeBase64 (char *dbuf, char *buf128, int len)
void SendMail (char *email,char *body)
int OpenSocket (struct sockaddr *addr)
int main()
{
char EmailTo[] = "[email protected]"
char EmailContents[] = "From: \"lucy\"[email protected]>\r\n"
"To: \"dasiy\"[email protected]>\r\n"
"Subject: Hello\r\n\r\n"
"Hello World, Hello Email!"
SendMail(EmailTo, EmailContents)
return 0
}
char ConvertToBase64(char uc)
{
if(uc <26)
{
return 'A' + uc
}
if(uc <52)
{
return 'a' + (uc - 26)
}
if(uc <62)
{
return '0' + (uc - 52)
}
if(uc == 62)
{
return '+'
}
return '/'
}
// base64的实现
void EncodeBase64(char *dbuf, char *buf128, int len)
{
struct Base64Date6 *ddd = NULL
int i= 0
char buf[256] = {0}
char *tmp = NULL
char cc = '\0'
memset(buf, 0, 256)
strcpy_s(buf, 256, buf128)
for(i = 1i <= len/3i++)
{
tmp = buf + (i-1)*3
cc = tmp[2]
tmp[2] = tmp[0]
tmp[0] = cc
ddd = (struct Base64Date6 *)tmp
dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1)
dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2)
dbuf[(i-1)*4+2] = ConvertToBase64((unsigned int)ddd->d3)
dbuf[(i-1)*4+3] = ConvertToBase64((unsigned int)ddd->d4)
}
if(len % 3 == 1)
{
tmp = buf + (i-1)*3
cc = tmp[2]
tmp[2] = tmp[0]
tmp[0] = cc
ddd = (struct Base64Date6 *)tmp
dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1)
dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2)
dbuf[(i-1)*4+2] = '='
dbuf[(i-1)*4+3] = '='
}
if(len%3 == 2)
{
tmp = buf+(i-1)*3
cc = tmp[2]
tmp[2] = tmp[0]
tmp[0] = cc
ddd = (struct Base64Date6 *)tmp
dbuf[(i-1)*4+0] = ConvertToBase64((unsigned int)ddd->d1)
dbuf[(i-1)*4+1] = ConvertToBase64((unsigned int)ddd->d2)
dbuf[(i-1)*4+2] = ConvertToBase64((unsigned int)ddd->d3)
dbuf[(i-1)*4+3] = '='
}
return
}
// 发送邮件
void SendMail(char *email, char *body)
{
int sockfd = {0}
charbuf[1500] = {0}
charrbuf[1500] = {0}
charlogin[128] = {0}
charpass[128] = {0}
WSADATA WSAData
struct sockaddr_in their_addr = {0}
WSAStartup(MAKEWORD(2, 2), &WSAData)
memset(&their_addr, 0, sizeof(their_addr))
their_addr.sin_family = AF_INET
their_addr.sin_port = htons(25)
hostent* hptr = gethostbyname("smtp.126.com")
memcpy(&their_addr.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length)
printf("IP of smpt.126.com is : %d:%d:%d:%d\n",
their_addr.sin_addr.S_un.S_un_b.s_b1,
their_addr.sin_addr.S_un.S_un_b.s_b2,
their_addr.sin_addr.S_un.S_un_b.s_b3,
their_addr.sin_addr.S_un.S_un_b.s_b4)
// 连接邮件服务器,如果连接后没有响应,则2 秒后重新连接
sockfd = OpenSocket((struct sockaddr *)&their_addr)
memset(rbuf, 0, 1500)
while(recv(sockfd, rbuf, 1500, 0) == 0)
{
cout<<"reconnect..."<<endl
Sleep(2)
sockfd = OpenSocket((struct sockaddr *)&their_addr)
memset(rbuf, 0, 1500)
}
cout<<rbuf<<endl
// EHLO
memset(buf, 0, 1500)
sprintf_s(buf, 1500, "EHLO HYL-PC\r\n")
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"EHLO REceive: "<<rbuf<<endl
// AUTH LOGIN
memset(buf, 0, 1500)
sprintf_s(buf, 1500, "AUTH LOGIN\r\n")
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Auth Login Receive: "<<rbuf<<endl
// USER
memset(buf, 0, 1500)
sprintf_s(buf, 1500, "[email protected]")//你的邮箱账号
memset(login, 0, 128)
EncodeBase64(login, buf, strlen(buf))
sprintf_s(buf, 1500, "%s\r\n", login)
send(sockfd, buf, strlen(buf), 0)
cout<<"Base64 UserName: "<<buf<<endl
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"User Login Receive: "<<rbuf<<endl
// PASSWORD
sprintf_s(buf, 1500, "XXXXXXXXXXXX")//你的邮箱密码
memset(pass, 0, 128)
EncodeBase64(pass, buf, strlen(buf))
sprintf_s(buf, 1500, "%s\r\n", pass)
send(sockfd, buf, strlen(buf), 0)
cout<<"Base64 Password: "<<buf<<endl
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Send Password Receive: "<<rbuf<<endl
// MAIL FROM
memset(buf, 0, 1500)
sprintf_s(buf, 1500, "MAIL FROM: [email protected]>\r\n")
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"set Mail From Receive: "<<rbuf<<endl
// RCPT TO 第一个收件人
sprintf_s(buf, 1500, "RCPT TO:<%s>\r\n", email)
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Tell Sendto Receive: "<<rbuf<<endl
// DATA 准备开始发送邮件内容
sprintf_s(buf, 1500, "DATA\r\n")
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Send Mail Prepare Receive: "<<rbuf<<endl
// 发送邮件内容,\r\n.\r\n内容结束标记
sprintf_s(buf, 1500, "%s\r\n.\r\n", body)
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Send Mail Receive: "<<rbuf<<endl
// QUIT
sprintf_s(buf, 1500, "QUIT\r\n")
send(sockfd, buf, strlen(buf), 0)
memset(rbuf, 0, 1500)
recv(sockfd, rbuf, 1500, 0)
cout<<"Quit Receive: "<<rbuf<<endl
//清理工作
closesocket(sockfd)
WSACleanup()
return
}
// 打开TCP Socket连接
int OpenSocket(struct sockaddr *addr)
{
int sockfd = 0
sockfd=socket(PF_INET, SOCK_STREAM, 0)
if(sockfd <0)
{
cout<<"Open sockfd(TCP) error!"<<endl
exit(-1)
}
if(connect(sockfd, addr, sizeof(struct sockaddr)) <0)
{
cout<<"Connect sockfd(TCP) error!"<<endl
exit(-1)
}
return sockfd
}
BOOL exSetTestBands(LPBYTE lpLinear, short height, long stride){ //set gray and color bands to dib and buffer 0
int i, j, k
short bwid = 30
short offx, offy
//set bands
if (!lpLinear) return FALSE
for (i=0 i<height i++)
FillMemory(lpLinear+stride*i, stride, i)
offy = min(256, height/2)
for (i=offy i<height i++)
{
FillMemory(lpLinear+stride*i, stride/2, i-offy)
for (k=0, j=stride/2 j<stride j+=24, k+=18)
{
FillMemory(lpLinear+stride*i+j, 24, k)
}
}
offy = 0
//black
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0x0
}
offy = i
offx = 0
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0x0
}
}
//blue
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xff
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xff
}
}
//green
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xff00
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xff00
}
}
//cyan
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xffff
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xffff
}
}
//red
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xff0000
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xff0000
}
}
//magenta
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xff00ff
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xff00ff
}
}
//yellow
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xffff00
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xffff00
}
}
//white
for (i=offy i<offy+32 i++)
{
for (j=stride/2 j<stride j+=3)
*(DWORD *)(lpLinear+stride*i+j) = 0xffffff
}
offy = i
offx += bwid
for (i=0 i<min(256,height/2) i++)
{
for (j=offx j<offx+bwid j+=3)
{
*(DWORD *)(lpLinear+stride*i+j) = 0xffffff
}
}
//repeat
offx += bwid
while (stride/2>offx) //remain
{
for (i=0 i<min(256,height/2) i++)
{
memcpy(lpLinear+stride*i+offx, lpLinear+stride*i, stride/2-offx)
}
offx += bwid*8
}
return 1
}
BOOL exOutReport(HDC hPr, LPBITMAPINFOHEADER lpbi, LPSTR lpdib)
{
char szLine[1024]
char str[50]
int startx
SIZE sSize
RECT rect
HFONT hFont, hOldFont
int Horz, Vert
float XZoom, YZoom
TEXTMETRIC TextMetric /* information about character size */
Horz = GetDeviceCaps(hPr, HORZRES)
XZoom = (float)Horz/2400 //in standard of 300dpi for A4
Vert = GetDeviceCaps(hPr, VERTRES)
YZoom = (float)Vert/3300
rect.top = (int)(600*YZoom)
rect.bottom = (int)(2600*YZoom)
// Set hospital name
hFont = CreateFont((int)(90*YZoom), (int)(35*XZoom), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL)
hOldFont = (HFONT)SelectObject(hPr, hFont)
GetTextMetrics(hPr, &TextMetric)
Rectangle(hPr, (int)(100*XZoom), (int)(155*YZoom), (int)((Horz-100)*XZoom), (int)(156*YZoom)) //underline
strcpy(szLine, "中国医科院北京肿瘤医院")
GetTextExtentPoint32(hPr, szLine, strlen(szLine), &sSize)
startx = (Horz-sSize.cx)/2
TextOut(hPr, startx, (int)(50*YZoom), (LPSTR)szLine, strlen(szLine))
SelectObject(hPr, hOldFont)
DeleteObject(hFont)
// set date contents
hFont = CreateFont((int)(62*YZoom), (int)(22*XZoom), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL)
hOldFont = (HFONT)SelectObject(hPr, hFont)
//year-month-date
strcpy(szLine, "打印日期: ")
_strdate(str)
str[2] = 0
str[5] = 0
str[8] = 0
strcat(szLine, str+6)
strcat(szLine, "-")//"年")
strcat(szLine, str)
strcat(szLine, "-")//"月")
strcat(szLine, str+3)
//strcat(szLine,"日")
TextOut(hPr, (int)(1600*XZoom), (int)(200*YZoom), (LPSTR)szLine, strlen(szLine))
//delete font
SelectObject(hPr, hOldFont)
DeleteObject(hFont)
rect.right = (int)((float)lpbi->biWidth/lpbi->biHeight
*(rect.bottom-rect.top))
rect.left = (int)((Horz-rect.right)/2+100*XZoom)
rect.right += rect.left
if (rect.left < 0)
{
rect.left = (int)(100*XZoom)
rect.right = (int)(2200*XZoom)
rect.bottom = (int)((float)lpbi->biHeight/lpbi->biWidth
*(rect.right-rect.left))+rect.top
}
StretchDIBits (hPr, // DestDC
rect.left, // DestX
rect.top, // DestY
rect.right - rect.left, // DestWidth
rect.bottom - rect.top, // DestHeight
0, // SrcX
0, // SrcY
(int)lpbi->biWidth, // SrcWidth
(int)lpbi->biHeight, // SrcHeight
lpdib, // lpBits
(LPBITMAPINFO) lpbi, // lpBitInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY) // dwROP
return 1
}
void COkMfcView::OnPrintpic()
{
// TODO: Add your command handler code here
//打印图像
CPrintDialog cpd = (FALSE, PD_ALLPAGES)
HDC hPr
CDC cdc
DOCINFO docinfo
cpd.DoModal()
hPr = cpd.GetPrinterDC()
if (!hPr) return
cdc.Attach(hPr)
docinfo.cbSize = sizeof(DOCINFO)
docinfo.lpszDocName = "prnfile"
docinfo.lpszOutput = NULL
docinfo.lpszDatatype = NULL
docinfo.fwType = 0
if (cdc.StartDoc(&docinfo) == -1) return
cdc.StartPage()
exOutReport(hPr, lpbi, lpdib)
cdc.EndPage()
cdc.EndDoc()
}
void COkMfcView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
RECT rcRect
POINT pt
int x,y
char szString[100]={0}
if (bActive)
return
rcRect.left=LOWORD(lScrnOffset)
rcRect.top=HIWORD(lScrnOffset)
rcRect.right=rcRect.left+lpbi->biWidth
rcRect.bottom=rcRect.top+lpbi->biHeight
MapWindowPoints((CWnd*)HWND_DESKTOP,(LPPOINT)&rcRect,2)
pt.x = point.x
pt.y = point.y
MapWindowPoints((CWnd*)HWND_DESKTOP,(LPPOINT)&pt,1)
x=pt.x-rcRect.left
y=pt.y-rcRect.top
if( (x>=0) && (x<lpbi->biWidth) && (y>=0) && (y<lpbi->biHeight) )
{
WORD gray
WORD r,g,b
LPBYTE lpPixel
long stride
long form,bufform
BYTE byBits
char szSource[32]
//1. screen
form=okSetCaptureParam(hBoard,CAPTURE_SCRRGBFORMAT,GETCURRPARAM) //-1
byBits=(BYTE)HIWORD(form)
if( okGetCaptureStatus(hBoard,0) ) { //capturing
lpPixel=(LPBYTE)okGetTargetInfo(hBoard, SCREEN, 0, NULL, NULL, &stride)
lpPixel+=pt.x*byBits/8+pt.y*stride
strcpy(szSource,"SCREEN")
}
else { //forzen
//wbytes=((((lpbi->biWidth*bits)+31)&~31)>>3)//bmp need 4 byte align
byBits=(BYTE)lpbi->biBitCount
stride=(lpbi->biWidth*byBits/8+3)/4*4 //dword align
lpPixel=(LPBYTE)lpdib+x*byBits/8+(lpbi->biHeight-y-1)*stride
strcpy(szSource,"DIB")
}
if(byBits<=8) { //8 bits
gray=*lpPixel
//gray=(BYTE)okReadPixel(hBoard,SCREEN,0,x,y-10)
//okWritePixel(hBoard,SCREEN,0,x,y-10,0x00ffff)
//sprintf(szString,"(%4i,%4i) = %s (%3i) ",pt.x-rcRect.left,pt.y-rcRect.top,szSource,gray)
}
else {
WORD wPixel
DWORD dwPixel
if(LOWORD(form)==FORM_RGB555) {
wPixel=((LPWORD)lpPixel)[0]
b= (wPixel&0x1f)<<3
g= ((wPixel>>5)&0x1f)<<3
r= ((wPixel>>10)&0x1f)<<3
}
else if(byBits==16) {
wPixel=((LPWORD)lpPixel)[0]
b= (wPixel&0x1f)<<3
g= ((wPixel>>5)&0x3f)<<2
r= ((wPixel>>11)&0x1f)<<3
}
else if(byBits>=24) {
dwPixel=((LPDWORD)lpPixel)[0]
//ShowCursor(0) //
//dwPixel=okReadPixel(hBoard,SCREEN,0,x,y) //$
//okWritePixel(hBoard,SCREEN,0,x,y,0x00ffff)//$
//ShowCursor(1)
b= (BYTE)(dwPixel&0xff)
g= (BYTE)(dwPixel>>8)&0xff
r= (BYTE)(dwPixel>>16)&0xff
}
sprintf(szString,"(%4i,%4i) = %s (%3i,%3i,%3i) ",pt.x-rcRect.left,pt.y-rcRect.top,
szSource,r,g,b)
}
//2. buffer
bufform=okSetCaptureParam(hBoard,CAPTURE_BUFRGBFORMAT,GETCURRPARAM) //-1
if( LOWORD(bufform)!= LOWORD(form) ) {
long dwPixel
dwPixel=okReadPixel(hBoard,BUFFER,-1,(short)x,(short)y) // read current frame
switch (LOWORD(bufform) ) {
case FORM_GRAY8:
case FORM_GRAY888:
case FORM_GRAY8888:
//dwPixel&=0xff
case FORM_GRAY10:
//dwPixel&=0x3ff
case FORM_GRAY12:
//dwPixel&=0xfff
case FORM_GRAY16: //gray
//dwPixel&=0xffff
sprintf(szString+strlen(szString)," BUFFER (%5i)",dwPixel)
break
//color
case FORM_RGB555:
b= (WORD)((dwPixel&0x1f)<<3)
g= (WORD)(((dwPixel>>5)&0x1f)<<3)
r= (WORD)(((dwPixel>>10)&0x1f)<<3)
sprintf(szString+strlen(szString)," BUFFER (%4i,%4i,%4i)",r,g,b)
break
case FORM_RGB888:
case FORM_RGB8888:
case FORM_RGB8886:
b= (WORD)(dwPixel&0xff)
g= (WORD)((dwPixel>>8)&0xff)
r= (WORD)((dwPixel>>16)&0xff)
if(LOWORD(bufform)==FORM_RGB8886) {
b=(b<<2) | (WORD)((dwPixel>>24)&0x3)
g=(g<<2) | (WORD)((dwPixel>>26)&0x3)
r=(r<<2) | (WORD)((dwPixel>>28)&0x3)
}
sprintf(szString+strlen(szString)," BUFFER (%4i,%4i,%4i)",r,g,b)
break
default:
//if(LOWORD(bufform)==FORM_RGB565) {
b= (WORD)((dwPixel&0x1f)<<3)
g= (WORD)(((dwPixel>>5)&0x3f)<<2)
r= (WORD)(((dwPixel>>11)&0x1f)<<3)
sprintf(szString+strlen(szString)," BUFFER (%4i,%4i,%4i)",r,g,b)
break
}
}
}
sBar->SetPaneText(0, szString)
return
}
void COkMfcView::OnSyshelp()
{
// TODO: Add your command handler code here
//系统帮助
::WinHelp(hWnd, "okHelp.hlp", HELP_HELPONHELP, 0)
}
void COkMfcView::OnCorr()
{
// TODO: Add your command handler code here
//相关内容
::WinHelp(hWnd, "okdemo.hlp", HELP_FINDER, 0)
}
#include "stdio.h"void main()
{
float a,b
printf("请输入包裹的重量(公斤):\n")
scanf("%f",&a)
if(a<=1)
b=1.5
else
{
b=1.5+(a-1)*0.8
}
printf("此包裹的邮费为:%.2f元",b)
}