📄 pop3.cpp
字号:
// Pop3.cpp: implementation of the CPop3 class.
//
//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
// 2003.1.1 功能基本完成
//
//
//
//
//
//
//
//
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <process.h>
#include "Pop3Monitor.h"
#include "Pop3.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//CPop3::CPop3(HWND hWnd)
CPop3::CPop3()
{
m_bSocketOK = false;
m_bConnected = false;
m_bReceiving = false;
m_sPop3Socket = INVALID_SOCKET;
m_hThreadHandle = NULL;
m_dwThreadId = 0;
m_dwTimeout = 20000;
m_lReceiveBufSize = RECEIVEBUFSIZE;
m_szReceiveBuf = new CHAR[m_lReceiveBufSize+1];
m_fpTmp = NULL;
#ifndef USE_CSTRING
m_szReceive = NULL;
m_lReceive = 0;
#endif
m_hEventWaitingRespond = CreateEvent(NULL , TRUE , FALSE , "Waiting for POP3 Server Respond");
ResetEvent(m_hEventWaitingRespond);
m_hEventExitThread = CreateEvent(NULL , TRUE , FALSE , "Waiting Thread Exit");
ResetEvent(m_hEventExitThread);
}
CPop3::~CPop3()
{
CloseHandle(m_hEventWaitingRespond);
CloseHandle(m_hEventExitThread);
#ifndef USE_CSTRING
if( NULL != m_szReceive )
delete []m_szReceive;
#endif
if( NULL != m_szReceiveBuf )
delete []m_szReceiveBuf;
}
BOOL CPop3::SetReceiveBufSize(long lSize)
{
if( NULL != m_szReceiveBuf )
{
delete []m_szReceiveBuf;
m_szReceiveBuf = NULL;
}
m_lReceiveBufSize = lSize;
m_szReceiveBuf = new CHAR[m_lReceiveBufSize+1];
return true;
}
BOOL CPop3::GetReceiveBufSize(long *lSize)
{
*lSize = m_lReceiveBufSize;
return true;
}
BOOL CPop3::SetTimeOut(DWORD dwTimeOut)
{
m_dwTimeout = dwTimeOut;
return true;
}
BOOL CPop3::GetTimeOut(DWORD *dwTimeOut)
{
*dwTimeOut = m_dwTimeout;
return true;
}
BOOL CPop3::GetLastError(CString *msg)
{
if( !m_strLastError.IsEmpty() )
*msg = m_strLastError;
return true;
}
BOOL CPop3::SetLastError(CString msg)
{
m_strLastError = msg;
return true;
}
BOOL CPop3::Create(LPCSTR pszHostName, int nPort)
{
struct sockaddr_in server;
struct hostent *hp;
unsigned int addr;
WSADATA wsaData;
CString strResult;
int nStart , nEnd;
if( m_bSocketOK )
Close();
m_bSocketOK = false;
m_bConnected = false;
m_hThreadHandle = NULL;
ResetEvent(m_hEventWaitingRespond);
ResetEvent(m_hEventExitThread);
BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(ret != 0)
{
SetLastError("Initialize Socket Fail!");
return false;
}
if( m_sPop3Socket != INVALID_SOCKET )
{
shutdown (m_sPop3Socket, 0x00);
closesocket(m_sPop3Socket);
}
m_sPop3Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_sPop3Socket == INVALID_SOCKET)
{
SetLastError("Create Socket Fail!");
goto error_return;
}
if(inet_addr(pszHostName)==INADDR_NONE)
{
hp=gethostbyname(pszHostName);
if( NULL == hp )
{
SetLastError("Hostname Error!");
goto error_return;
}
}
else
{
addr=inet_addr(pszHostName);
hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
if( NULL == hp )
{
SetLastError("Hostname Error!");
goto error_return;
}
}
server.sin_family = AF_INET;
server.sin_port = htons(nPort);
server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
if(connect(m_sPop3Socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
SetLastError("Connect POP3 Server Fail!");
goto error_return;
}
else
{
SetLastError("Connect POP3 Server Succeed!");
}
//create thread to get network event
m_hThreadHandle = (HANDLE) _beginthreadex(NULL, 0,
(PBEGINTHREADEX_THREADFUNC)MessageLoopThread,
(LPVOID)this, 0, (PBEGINTHREADEX_THREADID)&m_dwThreadId );
m_bSocketOK = true;
if( !GetSocketResult(&strResult , COMMAND_END_FLAG) )
return false;
nStart = strResult.Find('<' , 0);
nEnd = strResult.Find('>' , nStart);
if( nStart >= 0 && nEnd > nStart )
m_strTimeStamp = strResult.Mid(nStart , nEnd-nStart+1 );
else
m_strTimeStamp = "";
return true;
error_return:
shutdown (m_sPop3Socket, 0x00);
closesocket(m_sPop3Socket);
m_sPop3Socket = INVALID_SOCKET;
return false;
}
BOOL CPop3::Close()
{
DisConnect();
WaitForThreadExit();
// Disable receiving on ServerSock.
shutdown( m_sPop3Socket, 0x00 );
// Close the socket.
closesocket( m_sPop3Socket );
WSACleanup();
m_bSocketOK = false;
m_bConnected = false;
return true;
}
void CPop3::WaitForThreadExit()
{
if( NULL == m_hThreadHandle )
return;
SetEvent(m_hEventExitThread);
WaitForSingleObject(m_hThreadHandle , INFINITE);
CloseHandle(m_hThreadHandle);
m_hThreadHandle = NULL;
}
BOOL CPop3::Connect(LPCSTR pszUser, LPCSTR pszPassword , BOOL bAPOPAuthentication)
{
char msg[255];
int ret;
CString strResult;
CString strMD5Source;
CString strMD5Dst;
m_bConnected = false;
if( false == m_bSocketOK )
{
SetLastError("Socket not Create!");
return false;
}
if( bAPOPAuthentication )
{
if( m_strTimeStamp.IsEmpty() )
{
SetLastError("Apop error!");
return false;
}
strMD5Source = m_strTimeStamp+pszPassword;
strMD5Dst = MD5_GetMD5( (BYTE*)(const char*)strMD5Source , strMD5Source.GetLength() );
sprintf(msg , "apop %s %s\r\n" , pszUser , strMD5Dst);
ret = send(m_sPop3Socket , msg , strlen(msg) , NULL);
if(ret == SOCKET_ERROR)
{
SetLastError("Socket error!");
m_bSocketOK = false;
m_bConnected = false;
return false;
}
if( !GetSocketResult(&strResult , COMMAND_END_FLAG) )
return false;
if( 0 == strResult.Find('-' , 0) )
{
SetLastError("Username or Password error!");
return false;
}
m_bConnected = true;
}
else
{
sprintf(msg , "user %s\r\n" , pszUser);
ret = send(m_sPop3Socket , msg , strlen(msg) , NULL);
if(ret == SOCKET_ERROR)
{
SetLastError("Socket error!");
m_bSocketOK = false;
m_bConnected = false;
return false;
}
if( !GetSocketResult(&strResult , COMMAND_END_FLAG) )
return false;
if( 0 == strResult.Find('-' , 0) )
{
SetLastError("User Name error!");
return false;
}
sprintf(msg , "pass %s\r\n", pszPassword);
ret = send(m_sPop3Socket , msg , strlen(msg) , NULL);
if(ret == SOCKET_ERROR)
{
SetLastError("Socket error!");
m_bSocketOK = false;
m_bConnected = false;
return false;
}
if( !GetSocketResult(&strResult , COMMAND_END_FLAG) )
return false;
if( 0 == strResult.Find('-' , 0) )
{
SetLastError("User or Password error!");
return false;
}
m_bConnected = true;
}
return true;
}
BOOL CPop3::DisConnect()
{
CString strResult;
char msg[255];
int ret;
BOOL bRet = false;
if( false == m_bSocketOK )
{
SetLastError("Socket not Create!");
return false;
}
if( false == m_bConnected )
{
SetLastError("Not Connected!");
return false;
}
sprintf(msg , "quit\r\n");
ret = send(m_sPop3Socket , msg , strlen(msg) , NULL);
if(ret == SOCKET_ERROR)
{
SetLastError("Socket error!");
bRet = false;
}
else
bRet = true;
m_bSocketOK = false;
m_bConnected = false;
return bRet;
}
DWORD WINAPI CPop3::MessageLoopThread(LPVOID param)
{
int iRet;
#ifndef USE_CSTRING
CHAR *cTmp;
#endif
CPop3 *pto = (CPop3*)param;
if((pto->m_hEvent[0]=WSACreateEvent())==WSA_INVALID_EVENT)
{
pto->SetLastError("WSACreateEvent error!");
return 0;
}
pto->m_hEvent[1] = pto->m_hEventExitThread;
//if(WSAEventSelect( pto->m_sPop3Socket,pto->m_hEvent[0],FD_READ|FD_CLOSE|FD_ACCEPT|FD_CONNECT)!=SOCKET_ERROR)
if(WSAEventSelect( pto->m_sPop3Socket,pto->m_hEvent[0],FD_READ|FD_CLOSE)!=SOCKET_ERROR)
{
pto->SetLastError("Event Select ok!");
}
else
{
pto->SetLastError("Event Select Error!");
WSACloseEvent(pto->m_hEvent[0]);
return 0;
}
while( true )
{
pto->m_bReceiving = false;
DWORD m_Flag=WSAWaitForMultipleEvents(2,pto->m_hEvent,false,INFINITE,false);
pto->m_bReceiving = true;
switch(m_Flag)
{
case WSA_WAIT_EVENT_0:
WSANETWORKEVENTS we;
iRet=WSAEnumNetworkEvents(pto->m_sPop3Socket,pto->m_hEvent[0],&we);
if( we.lNetworkEvents & FD_READ )
{
if( !pto->m_bSocketOK )
{
WSACloseEvent(pto->m_hEvent[0]);
_endthreadex( 0 );
}
while( true )
{
memset(pto->m_szReceiveBuf , 0 , pto->m_lReceiveBufSize);
Sleep(3);
iRet = recv(pto->m_sPop3Socket , pto->m_szReceiveBuf , pto->m_lReceiveBufSize , NULL);
if(iRet == SOCKET_ERROR)
{
pto->m_strLastError = "Socket Read Error!";
goto error_return;
}
else if( pto->m_fpTmp != NULL )//write file mode
{
if( 1 > fwrite(pto->m_szReceiveBuf , iRet , 1 , pto->m_fpTmp) )
{
pto->m_strLastError = "Write tmp file Error!";
goto error_return;
}
if( iRet < pto->m_lReceiveBufSize )
break;
else
continue;
}
#ifdef USE_CSTRING
else
{
pto->m_szReceiveBuf[iRet] = '\0';
pto->m_strReceive += pto->m_szReceiveBuf;
if( iRet < pto->m_lReceiveBufSize )
break;
else
continue;
}
#else
else
{
if( NULL != pto->m_szReceive )
{
try
{
cTmp = new CHAR[pto->m_lReceive];
}
catch( bad_alloc err)
{
pto->SetLastError("Memory Error!");
goto error_return;
}
memcpy(cTmp , pto->m_szReceive , pto->m_lReceive);
delete []pto->m_szReceive;
try
{
pto->m_szReceive = new CHAR[pto->m_lReceive+iRet+1];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -