看了下邮件的发送与接收,了解了这方面知识,写一个帖子。
1、设置捕获
int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE h0, LPTSTR lpCmdLine, int nCmdShow)
{
BOOL bRet;
MSG msg;
HWND hwndFrame;
[B][COLOR="Red"] g_previousFilter = SetUnhandledExceptionFilter(TopLevelExceptionFilter);[/COLOR][/B]
//_CrtSetBreakAlloc(58);
InitCommonControls();
g_hInst = hInst;
//hModUxTheme = LoadLibrary(L"uxtheme.dll");
//注册框架窗口类
//创建框架窗口
//消息泵
//if (hModUxTheme)
//FreeLibrary(hModUxTheme);
_CrtDumpMemoryLeaks();
return (int) bRet;
}
2、捕获处理
LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo)
{
SYSTEMTIME time;
LONG lRet = EXCEPTION_CONTINUE_SEARCH;
//HRESULT hr ;
int end;
GetLocalTime(&time);
char acBuf[MAX_PATH] = {0};
// Build a string showing the date and time.
//Returns the number of characters written to the buffer, excluding any terminating NULL characters. A negative value is returned if an error occurs.
end = wnsprintfA(acBuf, MAX_PATH, "%d%02d%02d%02d%02d%02d.dmp",time.wYear,
time.wMonth, time.wDay,time.wHour, time.wMinute,time.wSecond);
if(end > 0)
{
HANDLE hFile;
char szBugFile[MAX_PATH+1] = {0};
GetModuleFileNameA(NULL,szBugFile,MAX_PATH + 1);
PathRemoveFileSpecA(szBugFile);
PathAppendA(szBugFile,acBuf);
hFile = CreateFileA(szBugFile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
;
//WriteLog(_T("ExceptionInfo"),_T("CreateFile"),_T("-1"));
}else{
BOOL (__stdcall *fnMiniDumpWriteDump)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,
PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION);
//typedef BOOL (__stdcall *MiniDumpWriteDumpProc)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,
//PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION);
HINSTANCE hinstLib;
//BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
//MiniDumpWriteDumpProc fnMiniDumpWriteDump;
hinstLib = LoadLibrary(TEXT("DbgHelp.dll"));
if(hinstLib)
{
(FARPROC&)fnMiniDumpWriteDump = ::GetProcAddress(hinstLib, "MiniDumpWriteDump");
//fnMiniDumpWriteDump = ( MiniDumpWriteDumpProc)::GetProcAddress(hinstLib, _T("MiniDumpWriteDump"));
if(fnMiniDumpWriteDump )
{
MINIDUMP_EXCEPTION_INFORMATION info;
info.ThreadId = ::GetCurrentThreadId();
info.ExceptionPointers = pExceptionInfo;
info.ClientPointers = FALSE;
BOOL bOk = fnMiniDumpWriteDump(::GetCurrentProcess,::GetCurrentProcessId(),hFile,MiniDumpNormal,&info,NULL,NULL);
if(bOk == FALSE)
WriteLog(_T("ExceptionInfo"),_T("MiniDumpWriteDump"),_T("error(0x%x)"),GetLastError());
HWND hBug = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_BUGDLG), NULL, (DLGPROC)BugDlgProc,(LPARAM)&info);
SetWindowLong(hBug,GWL_USERDATA,(LONG)szBugFile);
ShowWindow(hBug,SW_NORMAL);
BOOL bRet;
MSG msg;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// Handle the error and possibly exit
break;
}
else if (!IsWindow(hBug) || !IsDialogMessage(hBug, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
lRet = EXCEPTION_EXECUTE_HANDLER;
}else
WriteLog(_T("ExceptionInfo"),_T("MiniDumpWriteDump"),_T("Failed to get"));
FreeLibrary(hinstLib);
}else
WriteLog(_T("ExceptionInfo"),_T("DbgHelp.dll"),_T("Failed to load"));
}
CloseHandle(hFile);
//SAFE_DELETE(g_pszBugFile);
}
//if(g_previousFilter)
// return g_previousFilter(pExceptionInfo);
//else
return lRet;
}
3、捕获后用户窗口界面消息处理
INT_PTR CALLBACK BugDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case CTLCOLOR_STATIC:
{
if(IDC_LINK == GetDlgCtrlID((HWND)lParam))
{
HBRUSH br = CreateSolidBrush( RGB(255,255,255) );
return (INT_PTR)br;
}
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BTNATTACH:
OnBugAddFiles(hWnd);
return 0;
case IDOK:
{
if(BST_CHECKED == IsDlgButtonChecked(hWnd,IDC_SUBMIT))
{
BugSendMail(hWnd);
}
if(BST_CHECKED == IsDlgButtonChecked(hWnd,IDC_REBOOT))
{
TCHAR pszAppPath[MAX_PATH + 1];
GetModuleFileName(NULL,pszAppPath,MAX_PATH + 1);
ShellExecute(NULL, NULL,pszAppPath, NULL, NULL, SW_SHOWNORMAL);
}
}
break;
case IDCANCEL:
DestroyWindow(hWnd);
}
break;
case WM_INITDIALOG:
{
CenterWindow(hWnd,NULL);
MINIDUMP_EXCEPTION_INFORMATION *pInfo = (MINIDUMP_EXCEPTION_INFORMATION*)lParam;
}
return TRUE;
case WM_DESTROY:
//SAFE_DELETE(g_pszAppPath);
PostQuitMessage(0);
break;
}
return FALSE;
}
//这里直接2个附件,多个附件需要改下Smtp类
void BugSendMail(HWND hWnd)
{
char acBugFile[MAX_PATH + 1] = {0};
GetDlgItemTextA(hWnd,IDC_ATTACHFILE,acBugFile,MAX_PATH + 1);
char* pMoreFile = (char*)GetWindowLong(hWnd,GWL_USERDATA);
SetCursor( LoadCursor(NULL, IDC_WAIT) );
Smtp smtp;
char acount[] = "";
DWORD dwSize;
char sName[MAX_COMPUTERNAME_LENGTH + 1];
dwSize = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerNameA(sName, &dwSize);
if(smtp.Connect("smtp.163.com") && smtp.Login(acount,"...")\
&& smtp.Send(acount,"...@qq.com",sName,"f","...",pData,acBugFile,pMoreFile,0))
;
else MessageBox(NULL,_T("send failed."),_T("bug"),MB_OK|MB_ICONERROR);
SetCursor( LoadCursor(NULL, IDC_ARROW) );
}
void CenterWindow(HWND hWnd,HWND hParent)
{
if(hParent == NULL)
hParent = GetDesktopWindow();
RECT rcParent,rc;
GetWindowRect(hParent, &rcParent);
GetWindowRect(hWnd, &rc);
int w = rc.right-rc.left,
h = rc.bottom-rc.top,
x = rcParent.right - rcParent.left -w,
y=rcParent.bottom - rcParent.top -h;
x = rcParent.left + (long)(x/2.0 + 0.5);
y = rcParent.top + (long)(y/2.0+0.5);
SetWindowPos(hWnd, HWND_TOP, x, y, 0, 0,SWP_NOSIZE);
}
5、检查更新
DWORD WINAPI UpdataThreadFunc( LPVOID lpParam )
{
Pop3 pop;
g_style |= UPDATA;
if(pop.Connect("pop.163.com") && pop.Login("xxx@163.com","xxx"))
{
int nSize,k = 0,nBufSize = 0;
int iCount = pop.Stat();
char *pSubject,*pSubjectEnd,*pUpdataVersion,*szBuf=0;
const char acUpdataFile[] = "Updataxx";
const char acVer[] = "Ver=";
const char acAddr[] = "Addr=";
const char acSub[] = "\r\nSUBJECT: ";
for(;iCount > 0 && (g_style & UPDATA);iCount--)
{
pSubject=pSubjectEnd=pUpdataVersion = 0;
nSize = pop.List(iCount);
if(nSize <= 0)
continue;
if(nBufSize < nSize)
{
SAFE_DELETE_ARRAY(szBuf);
nBufSize = nSize+1;
szBuf = new char[nBufSize];
}
nSize = pop.Retr(iCount,szBuf,nSize);
if(0 >= nSize)
continue;
szBuf[nSize] = 0;
//里面要放更新的内容,需要自己发邮件到此邮箱,简单的信息写在标题里就可以了然后解析,如xxx|ver=2.00|addr=xxx|xxx
}
end:
pop.Disconnect();
SAFE_DELETE_ARRAY(szBuf);
}
g_style &= ~UPDATA;
OutputDebugString(_T("UpdataThreadFunc return\n"));
return 0;
}
6、邮件类
#include "Base64.h"
#include <string>
using namespace std;
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
extern WORD g_style;
SOCKET InitSocket(WORD wVersionRequired = MAKEWORD(2,2)); // 创建
void ReleaseSocket(SOCKET hSOCKET); // 释放Socket
#define BOUNDARY "fang" // 边界字符串
#define for if(0); else for // 变量作用域
//缓冲区大小,这个值必须是57的整数倍!
#define BUFFER_READ 11400
class Smtp
{
public:
Smtp();
virtual ~Smtp();
private:
SOCKET m_SOCKET;
LPHOSTENT m_HOSTENT;
SOCKADDR_IN m_SOCKADDR_IN;
private:
/*
功能:
验证从服务器返回的前三位代码和传递进来的参数是否一样
备注:
211 帮助返回系统状态
214 帮助信息
220 服务准备就绪
221 关闭连接
235 用户验证成功
250 请求操作就绪
251 用户不在本地,转寄到其他路径
334 等待用户输入验证信息
354 开始邮件输入
421 服务不可用
450 操作未执行,邮箱忙
451 操作中止,本地错误
452 操作未执行,存储空间不足
500 命令不可识别或语言错误
501 参数语法错误
502 命令不支技
503 命令顺序错误
504 命令参数不支持
550 操作未执行,邮箱不可用
551 非本地用户
552 中止存储空间不足
553 操作未执行,邮箱名不正确
554 传输失败
*/
BOOL CheckResponse(const char* RecvCode);
BOOL SendFile(const char *szFile);
public:
//接smtp服务器
BOOL Connect(const char* SmtpAddr);//,const int Port
//验证用户名和密码
BOOL Login(const char* Username,const char* Password);
//发送数据
BOOL Send(const char* SendFrom, // 发送地址
const char* SendToList, // 目地地址列表
const char* SenderName, // 发送者姓名
const char* ReceiverName, // 接收者姓名
const char* Subject, // 邮件主题
const char* Content, // 邮件内容
const char* File1, // 附件1
const char* File2, // 附件2
BOOL IsHtml); // 是否以HTML格式发送
};
#endif
class Pop3
{
public:
Pop3();
virtual ~Pop3();
private:
BOOL m_bConnected;
SOCKET m_SOCKET;
LPHOSTENT m_HOSTENT;
SOCKADDR_IN m_SOCKADDR_IN;
public:
BOOL Connect(const char* ServerAddr,const int Port = 110);
BOOL CheckResponse(const char* Action, char *pBuf = NULL, int cSize = 0);
BOOL Login(const char *Username,const char *Password);
BOOL Disconnect();
/*(STAT)
该命令请求服务器返回信箱大小的信息,但是不包过标记为删除的邮件
Client:STAT
Server:+OK 2 4065
服务器的应答包含信箱的数量以及所有邮件的大小。stat命令仅在事务状态时可用的
*/
int Stat(DWORD *dwTotalSize = NULL);
BOOL Dele( UINT iIndex );
int Retr(UINT iIndex,char *Msg, int cMsg);
/* 列表(LIST) 参数0全部,返回数量=STAT;其他返回大小,否则-1错误
该命令请求服务器返回一个信箱中特定邮件的大小信息或者没有删除标记的所有邮件的大小信息
Client: LIST 1
Server:+OK 1 1046
该命令有两种使用情形,带参和不带参。List后面如果指定邮件,则返回邮件大小信息,如上所示。 List指定的邮件如果被标识为删除或者不存在,则出错,如下所示:
Client:LIST 5
Server:-ERR no such message ,only message 1 thru 1 are present in your inbox
如果List不带参数,如下所示:
Client:LIST
Server将返回多行应答。
+OK
1 1045
2 2204
.
应答成功先是相应+OK,接着每一行含有一个邮件号和邮件的大小(字节数),最后是以句点"."作为结束 行。
*/
int List(int iIndex = 0);
};
#include "mail.h"
#include "..\header.h"
SOCKET InitSocket(WORD wVersionRequired)
{
WSADATA WSAData;
SOCKET hServer;
if(WSAStartup(wVersionRequired,&WSAData) == SOCKET_ERROR)
return SOCKET_ERROR;
// Create a TCP/IP socket, no specific protocol.
hServer = socket(AF_INET,SOCK_STREAM,0);
return hServer;
}
void ReleaseSocket(SOCKET hSOCKET)
{
if(hSOCKET != SOCKET_ERROR)
{
shutdown( hSOCKET,SD_BOTH);
closesocket( hSOCKET);
}
WSACleanup();
}
Smtp::Smtp()
{
}
Smtp::~Smtp()
{
ReleaseSocket(m_SOCKET);
}
BOOL Smtp::CheckResponse(const char* RecvCode)
{
try
{
char Buf[1024]={0};
if(recv(m_SOCKET,Buf,1024,0) == SOCKET_ERROR)
{
WriteLog(_T("bugsend"),_T("CheckRecv"),_T("error:%ld"),WSAGetLastError());
return false;
}
if(RecvCode[0] == Buf[0] && RecvCode[1] == Buf[1] && RecvCode[2] == Buf[2])
return TRUE;
WriteLogA("bugsend","CheckRecv",Buf);
return false;
}
catch(...)
{
return false;
}
}
BOOL Smtp::Connect(const char* ServerAddr)//,const int Port
{
LPSERVENT lpServEntry;
int iProtocolPort;
if((m_SOCKET =InitSocket(MAKEWORD(2,2))) == SOCKET_ERROR)
return false;
// Lookup email server's IP address.
if((m_HOSTENT = gethostbyname(ServerAddr))==NULL)
{
return false;
}
if(m_HOSTENT->h_addr_list[0] == NULL)
{
return false;
}
// Get the mail service port.
lpServEntry = getservbyname( "mail" , 0);
// Use the SMTP default port if no other port is specified.
if (lpServEntry == NULL)
iProtocolPort = htons(IPPORT_SMTP);
else
iProtocolPort = lpServEntry->s_port;
// Setup a Socket Address structure.
memset(&m_SOCKADDR_IN,0,sizeof(m_SOCKADDR_IN));
m_SOCKADDR_IN.sin_family = AF_INET;
m_SOCKADDR_IN.sin_port = iProtocolPort;//htons(Port)
m_SOCKADDR_IN.sin_addr.S_un.S_addr = *(ULONG *)m_HOSTENT->h_addr_list[0];
//连接服务器
if(connect(m_SOCKET,(sockaddr *)&m_SOCKADDR_IN,sizeof(m_SOCKADDR_IN)) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("220")) return false;
char szBuf[1024];
//向服务器发送"HELO "+服务器名
wnsprintfA(szBuf,1024,"HELO %s\r\n",ServerAddr);
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("250")) return false;
return true;
}
BOOL Smtp::Login(const char *Username,const char *Password)
{
Base64 base64;
int iRet;
//发送"AUTH LOGIN"
if(send(m_SOCKET,"AUTH LOGIN\r\n",lstrlenA("AUTH LOGIN\r\n"),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("334")) return false;
int iLength = lstrlenA(Username);
char *szEncode = new char[base64.GetEncodedLength(iLength) + 5];
char *pEnd = 0;
//发送经base64编码的用户名
pEnd = (char*)base64.Encode((unsigned char *)Username,iLength,(unsigned char*)szEncode,0);
lstrcpyA(pEnd,"\r\n");
iRet = send(m_SOCKET,szEncode,lstrlenA(szEncode),0);
SAFE_DELETE_ARRAY(szEncode);
if(iRet == SOCKET_ERROR)
return false;
if(!CheckResponse("334")) return false;
//发送经base64编码的密码
iLength = lstrlenA(Password);
szEncode = new char[base64.GetEncodedLength(iLength) + 5];
pEnd = (char*)base64.Encode((unsigned char *)Password,iLength,(unsigned char*)szEncode,0);
lstrcpyA(pEnd,"\r\n");
iRet = send(m_SOCKET,szEncode,lstrlenA(szEncode),0);
SAFE_DELETE_ARRAY(szEncode);
if(iRet == SOCKET_ERROR)
return false;
if(!CheckResponse("235")) return false;
return true;
}
BOOL Smtp::SendFile(const char *szFile)
{
if(szFile == NULL || szFile[0] == '\0') return false;
Base64 base64;
char szBuf[1024];
char *pFileName = PathFindFileNameA(szFile);
wnsprintfA(szBuf,1024,"--%s\r\n"\
"Content-Type:application/octet-stream;Name=\"%s\"\r\n"\
"Content-Disposition:attachment;FileName=\"%s\"\r\n"\
"Content-Transfer-Encoding:Base64\r\n\r\n"
,BOUNDARY,pFileName,pFileName);
if(SOCKET_ERROR == send(m_SOCKET,szBuf,lstrlenA(szBuf),0))
return false;
HANDLE fd;
fd=CreateFileA(szFile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(fd == INVALID_HANDLE_VALUE) {
DisplayError(_T("Create"));
return FALSE;
}
BOOL bRet = FALSE;
char encode[18000],Buf[BUFFER_READ+1];
int ccEncode;
DWORD ReadSize;
ReadFile(fd,Buf,BUFFER_READ,&ReadSize,0);
while(ReadSize==BUFFER_READ)
{
base64.Encode((unsigned char*)Buf,ReadSize,(unsigned char*)encode,&ccEncode);
if(send(m_SOCKET,encode,ccEncode,0) == SOCKET_ERROR)
{
goto end;
}
//memset(Buf,0,BUFFER_READ+1);
ReadFile(fd,Buf,BUFFER_READ,&ReadSize,0);
}
char *pEnd = (char*)base64.Encode((unsigned char*)Buf,ReadSize,(unsigned char*)encode,&ccEncode);
wnsprintfA(pEnd,5,"\r\n\r\n");
if(send(m_SOCKET,encode,ccEncode+4,0) == SOCKET_ERROR)
{
goto end;
}
bRet = TRUE;
end:
CloseHandle(fd);
return bRet;
}
BOOL Smtp::Send(const char* SendFrom, // 发送地址
const char* SendTo, // 目地地址
const char* SenderName, // 发送者姓名
const char* ReceiverName, // 接收者姓名
const char* Subject, // 邮件主题
const char* Content, // 邮件内容
const char* File1, // 附件1
const char* File2, // 附件2
BOOL IsHtml) // 是否以HTML格式发送
{
if(SendFrom == NULL || SendFrom[0] == '\0') return FALSE;
string strTmp;
char szBuf[1024];
//发送MAIL FROM:<abc@xyz.com>
wnsprintfA(szBuf,1024,"MAIL FROM:<%s>\r\n",SendFrom);
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("250")) return false;
//发送RCPT To:<abc@xyz.com>
wnsprintfA(szBuf,1024,"RCPT To:<%s>\r\n",SendTo);
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("250")) return false;
//发送"DATA\r\n"
wnsprintfA(szBuf,1024,"DATA\r\n");
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("354")) return false;
wnsprintfA(szBuf,1024,"From:%s<%s>\r\n"\
"Subject:%s\r\n"\
"MIME_Version:1.0\r\n"\
"X-Mailer:Generator\r\n"\
"MIME_Version:1.0\r\n"\
"Content-type:multipart/mixed;Boundary=\"%s\"\r\n\r\n"
,SenderName,SendFrom,Subject,BOUNDARY );
//先将HEADER部分发送过去
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
//邮件主体
wnsprintfA(szBuf,1024,"--%s\r\n"\
"Content-type:text/%s;Charset=gb2312\r\n"\
"Content-Transfer-Encoding:8bit\r\n\r\n"
,BOUNDARY,IsHtml ? "html" : "plain");
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
//将邮件内容发送出去
if(send(m_SOCKET,Content,lstrlenA(Content),0) == SOCKET_ERROR)
{
return false;
}
wnsprintfA(szBuf,1024,"\r\n\r\n");
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
/*
附件处理
对文件内容分段进行base64编码,编码一小段,传送一小段
*/
SendFile(File1);
SendFile(File2);
//界尾
wnsprintfA(szBuf,1024,"--"BOUNDARY"--\r\n.\r\n");
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("250")) return false;
//退出
wnsprintfA(szBuf,1024,"QUIT\r\n");
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
{
return false;
}
if(!CheckResponse("221")) return false;
return true;
}
Pop3::Pop3()
{
m_bConnected = FALSE;
}
Pop3::~Pop3()
{
if( m_bConnected )
Disconnect();
ReleaseSocket(m_SOCKET);
}
BOOL Pop3::CheckResponse(const char* Action,char* pBuf,int cSize)
{
try
{
char szBuf[1024];
int iLength;
if(pBuf == NULL)
{
pBuf = szBuf;
cSize = 1024;
}
iLength = recv(m_SOCKET,pBuf,cSize,0);
if(iLength == SOCKET_ERROR)
{
WriteLog(_T("updata"),_T("CheckRecv"),_T("error:%ld"),WSAGetLastError());
return FALSE;
}
if (0 == StrCmpNIA(pBuf,"-ERR",4))
{
WriteLogA("updata",Action,pBuf);
return FALSE;
}
return iLength;
}
catch(...)
{
return false;
}
}
BOOL Pop3::Connect(const char* ServerAddr,const int Port)
{
SOCKADDR_IN SockAddr;
//SOCKET hServer;
//LPSERVENT lpServEntry;
if((m_SOCKET = InitSocket(MAKEWORD(2,2))) == SOCKET_ERROR)
return false;
// Lookup email server's IP address.
if((m_HOSTENT = gethostbyname(ServerAddr))==NULL)
{
return false;
}
if(m_HOSTENT->h_addr_list[0] == NULL)
{
return false;
}
// Setup a Socket Address structure.
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(Port);
SockAddr.sin_addr = *((LPIN_ADDR)*m_HOSTENT->h_addr_list);
//int nNetTimeout = 30000; //30秒
//setsockopt(m_SOCKET,SOL_SOCKET,SO_RCVTIMEO,(char* )&nNetTimeout,sizeof(int));
// Connect the Socket.
if (connect( m_SOCKET, (PSOCKADDR) &SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
return FALSE;
if(!CheckResponse("connect server")) return false;
return TRUE;
}
BOOL Pop3::Login(const char *Username,const char *Password)
{
char szBuf[1024];
wnsprintfA(szBuf,1024,"USER %s\r\n",Username);
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
return false;
if(!CheckResponse("USER")) return FALSE;
wnsprintfA(szBuf,1024,"PASS %s\r\n",Password);
if(send(m_SOCKET,szBuf,lstrlenA(szBuf),0) == SOCKET_ERROR)
return false;
if(!CheckResponse("PASS")) return FALSE;
m_bConnected = TRUE;
return TRUE;
}
BOOL Pop3::Disconnect()
{
//BOOL ret;
if( !m_bConnected )
return TRUE;
// Disconnect gracefully from the server and close the socket
char szBuf[20];
lstrcpynA(szBuf,"QUIT\r\n",20);
send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
// No need to check return value here.If it fails, the message is available with GetLastError
m_bConnected = FALSE;
return CheckResponse("QUIT");
}
int Pop3::Stat(DWORD *dwTotalSize)
{
char szBuf[1024];
lstrcpynA(szBuf,"STAT\r\n",20);
send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
if( !CheckResponse("STAT",szBuf,1024) ) return -1;
char* pNum =StrPBrkA(szBuf,"0123456789");
if (pNum == NULL) return -1;
int sum = strtol(pNum,&pNum,10);
if(dwTotalSize)
*dwTotalSize = strtoul(pNum + 1,&pNum,10);
return sum;
}
BOOL Pop3::Dele( UINT iIndex )
{
char szBuf[1024];
wnsprintfA(szBuf,20,"DELE %d\r\n",iIndex);
send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
return CheckResponse("DELE");
}
int Pop3::List(int iIndex)
{
if(iIndex == 0)
return Stat();
char szBuf[1024];
wnsprintfA(szBuf,20,"LIST %d\r\n",iIndex);
send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
if(0 >= CheckResponse("LIST",szBuf,1024) ) return -1;
int i = 0,size = 0;
sscanf_s(szBuf,"%*s%d%d",&i, &size);
return size;
}
int Pop3::Retr( UINT iIndex,char *Msg, int cMsg)
{
if(iIndex <= 0 || Msg == 0 || !(g_style & UPDATA))
return -1;
char szBuf[1024];
int nChars,nHasRev = 0,nDesire = cMsg;
Msg[0] = '\0';
wnsprintfA(szBuf,1024,"RETR %d\r\n",iIndex);
send(m_SOCKET,szBuf,lstrlenA(szBuf),0);
//Sleep(1000);
nChars = CheckResponse("RETR",Msg,cMsg);
while(nDesire > 0 && (g_style & UPDATA))
{
if(nChars < 0){
// 由于是非阻塞的模式,所以当errno为EAGAIN时,表示当前缓冲区已无数据可读
// 在这里就当作是该次事件已处理处.
if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
nDesire = 1;
else
break;
}
//else if(nChars == 0)
// break;//这里表示对端的socket已正常关闭
//else if(nChars == nDesire)
// nDesire = 1;
if(nHasRev >= cMsg)//把缓冲区的内容拷完耗尽,免得下次拷到这里的内容
{
nChars = recv(m_SOCKET,szBuf,1024,0);
nDesire = 1024;
}
else
{
nHasRev += nChars;
nDesire = cMsg-nHasRev;
nChars = recv(m_SOCKET,Msg+nHasRev,nDesire,0);
}
}
return nHasRev;
}
#ifndef _BASE64
#define _BASE64
class Base64
{
public:
/*编码
DataByte
[in]输入的数据长度,以字节为单位
*/
unsigned char* Encode(const unsigned char* Data,int DataByte, unsigned char* strEncode,int *outLength);
int GetEncodedLength(int iLength);
/*解码
DataByte
[in]输入的数据长度,以字节为单位
OutByte
[out]输出的数据长度,以字节为单位,请不要通过返回值计算
输出数据的长度
*/
unsigned char* Decode(const char* Data,int DataByte,int& OutByte,unsigned char *strDecode);
};
#endif #include "Base64.h"
int Base64::GetEncodedLength(const int iLength)
{
return ((iLength/3 +1) << 2)+1;
}
unsigned char* Base64::Encode(const unsigned char* Data,int DataByte,unsigned char* strEncode,int *outLength)
{
//编码表
const char EncodeTable[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char Tmp[3]={0};
int LineLength=0,DataByte3 = (int)(DataByte / 3);
int iLength = 0;
for(int i=0; i < DataByte3; i++)
{
Tmp[0] = *Data++;
Tmp[1] = *Data++;
Tmp[2] = *Data++;
*strEncode++= EncodeTable[Tmp[0] >> 2];
*strEncode++= EncodeTable[((Tmp[0] << 4) | (Tmp[1] >> 4)) & 0x3F];
*strEncode++= EncodeTable[((Tmp[1] << 2) | (Tmp[2] >> 6)) & 0x3F];
*strEncode++= EncodeTable[Tmp[2] & 0x3F];
iLength += 4;
if(LineLength+=4,LineLength==76)
{
*strEncode++='\r';
*strEncode++='\n';
iLength += 2;
LineLength=0;
}
}
//对剩余数据进行编码
int Mod=DataByte % 3;
if(Mod==1)
{
Tmp[0] = *Data++;
*strEncode++ = EncodeTable[(Tmp[0] & 0xFC) >> 2];
*strEncode++ = EncodeTable[((Tmp[0] & 0x03) << 4)];
*strEncode++ = '=';
*strEncode++ = '=';
iLength += 4;
}
else if(Mod==2)
{
Tmp[0] = *Data++;
Tmp[1] = *Data++;
*strEncode++ = EncodeTable[(Tmp[0] & 0xFC) >> 2];
*strEncode++ = EncodeTable[((Tmp[0] & 0x03) << 4) | ((Tmp[1] & 0xF0) >> 4)];
*strEncode++ = EncodeTable[((Tmp[1] & 0x0F) << 2)];
*strEncode++ = '=';
iLength += 4;
}
if(outLength) *outLength = iLength;
return strEncode;
}
unsigned char* Base64::Decode(const char* Data,int DataByte,int& OutByte, unsigned char* strDecode)
{
//解码表
const char DecodeTable[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};
int nValue;
int i= 0;
while (i < DataByte)
{
if (*Data != '\r' && *Data!='\n')
{
nValue = DecodeTable[*Data++] << 18;
nValue += DecodeTable[*Data++] << 12;
*strDecode++=(nValue & 0x00FF0000) >> 16;
OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++] << 6;
*strDecode++=(nValue & 0x0000FF00) >> 8;
OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++];
*strDecode++=nValue & 0x000000FF;
OutByte++;
}
}
i += 4;
}
else// 回车换行,跳过
{
Data++;
i++;
}
}
return strDecode;
}
[课程]FART 脱壳王!加量不加价!FART作者讲授!