⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pop3.cpp

📁 一个简单的pop3接收邮件程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -