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

📄 mysock.cpp

📁 这是网络实用编程的随书的源代码,欢迎下载
💻 CPP
字号:
// mySock.cpp : implementation file
//

#include "stdafx.h"
#include "pop3.h"
#include "mySock.h"
#include  "pop3Dlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define MAX_BUFF 20000
/////////////////////////////////////////////////////////////////////////////
// mySock

//构造函数,对某些成员变量初始化
mySock::mySock()
{
	m_pDlg = NULL;
	state=FIRST;
	error="Not connected to server\r\n";
}

mySock::~mySock()
{
	m_pDlg = NULL;
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(mySock, CAsyncSocket)
	//{{AFX_MSG_MAP(mySock)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// mySock member functions
//接到此消息仅仅显示了一句话,开关了一些按钮连接成功后,服务器发来响应,因此
//又立即收到了OnReceive消息,后来的会话过程中,一来一往,程序总是收到
//OnReceive消息,所以真正的事情在那里作。
void mySock::OnConnect(int nErrorCode) 
{
	if(nErrorCode==0)  m_pDlg->Disp(S_CONNECT);
}

//服务器端关闭连接,才会收到此消息。
void mySock::OnClose(int nErrorCode) 
{
	if(nErrorCode==0)  m_pDlg->Disp(S_CLOSE);
}

//套接字收到服务器发来的数据时,执行此函数
void mySock::OnReceive(int nErrorCode) 
{
	if(nErrorCode==0) 
	{
		char buff[MAX_BUFF];            //接收缓冲区
		int rec=Receive(buff,MAX_BUFF); //接收服务器发来的数据
		buff[rec]=NULL;                  //结尾置为NULL。
		lastMsg=buff;
		AnalyzeMsg();                      //分析收到的数据,作不同的处理
	}  else  {
		error="在接收数据时发送了错误!\r\n";
		m_pDlg->Disp(S_CLOSE);   //显示信息
	}
}
//设置套接字类的对话框指针变量
void mySock::SetParent(CPop3Dlg *pDlg)
{
	m_pDlg = pDlg;
}

//获得第 i 封信件的标题信息
CString mySock::GetMsgStuff(int i)
{
	CString ret;
CString s;
	int where=msgs[i].text.Find("From:");

s.Format("From:位置:%d\r\n",where);
m_pDlg->m_Info+=s;
	
	if (where!=-1)
	{
		ret+=ReadLn(where,msgs[i].text);
		ret+="\r\n";
	}

	where=msgs[i].text.Find("To:");

s.Format("To:位置:%d\r\n",where);
m_pDlg->m_Info+=s;
	
	if (where!=-1)
	{
		ret+=ReadLn(where,msgs[i].text);
		ret+="\r\n";
	}
	
	where=msgs[i].text.Find("Date:");

s.Format("Date:位置:%d\r\n",where);
m_pDlg->m_Info+=s;
	
	if (where!=-1)
	{
		ret+=ReadLn(where,msgs[i].text);	
		ret+="\r\n";
	}
	ret+=GetMsgSubject(i);
	ret+="\r\n";
	return ret;

}

//获得第 i 封信件的信件体
CString mySock::GetMsgBody(int i)
{
	CString ret;
	int where=msgs[i].text.Find("\r\n\r\n");
	if(where!=-1) where+=4;
	else          where=0;
	ret=msgs[i].text.Right(msgs[i].text.GetLength()-where);
	ret=ret.Left(ret.GetLength()-3);
	return ret;
}

//获得第 i 封信件的标题
CString mySock::GetMsgSubject(int i)
{
//	CString s;
//	s.Format("%s",msgs[i].text);
//	int where=s.Find("Subject:");
	
	CString ret;
	int where=msgs[i].text.Find("Subject:");
	if (where!=-1) 	ret=ReadLn(where,msgs[i].text);
	else ret.Format("找不到Subject:");
	return ret;
}

//获得第 i 封信整封信的内容
CString mySock::GetMsg(int i)
{
	return msgs[i].text;
}

//从src串中,从index所指的位置开始,取子字串,直到行末符"\r"为止。
//dst是一个串的地址,取出的行追加在该串的原内容之后
CString mySock::ReadLn(int index,CString src)
{
//	CString comp;
//	CString dst;
//	comp=src[index];
//	while(comp!="\r")
//	{
//		dst+=comp;
//		comp=src[++index];
//	}
//	return dst;

	CString ret;
	CString s;
	
	ret=src.Right(src.GetLength()-index);
	int where=ret.Find("\r");
//	s.Format("行所在的位置:%d",where);
//	m_pDlg->m_Info+=s;
//	m_pDlg->UpdateData(FALSE);
	if(where!=-1) where+=1;
	else          where=0;
//	s.Format("行所在的位置:%d, Length=%d ",where,ret.GetLength());
//	m_pDlg->m_Info+=s;
//	m_pDlg->UpdateData(FALSE);
	
	ret=ret.Left(where);
	return ret;

}

 
 //退出服务器
void mySock::Close()
{
	CString str;
	str.Format("quit%c%c",13,10);
	Send((LPCSTR)str,str.GetLength());
	m_pDlg->Disp(S_CLOSE);
	state=FIRST;
	CAsyncSocket::Close();
	error="执行mySock::Close()命令,Not connected to server\r\n";
}

void mySock::AnalyzeMsg()
{
	int  ix;
	CString temp1;
	CString temp2;

	CString s;
	strstream str;
	string check;
	str<<(LPCSTR)lastMsg; //将收到的信息拷贝到字符流变量中  
	str>>check;           //提取所收到信息的第一段代码
	if(check=="-ERR")     //如果有错误
	{
		error="Received -ERR from server :"+lastMsg;
		Close(); //断开连接,然后关闭
		return;
	}
	
	//如果没有错误,则根据不同的会话阶段响应来处理
	switch(state) 
	{
	case FIRST: //如果已经连接成功,类初始化的时候state为FIRST
		msgs.clear();
		//显示连接成功后服务器返回的消息
		m_pDlg->Disp(S_RECEIVE); 
		//发送 user 用户名 命令
		s.Format("user %s%c%c",m_pDlg->m_strUser,13,10);
		Send((LPCSTR)s,s.GetLength()); //发送用户帐号
		state=USER;
		break;

	case USER:
		//显示服务器对于user命令的响应
		m_pDlg->Disp(S_RECEIVE);
		//发送 pass 口令 命令,发送密码
		s.Format("pass %s%c%c",m_pDlg->m_strPass,13,10); 
		Send((LPCSTR)s,s.GetLength()); 
		state=PASS;
		break;

	case PASS:
		//显示服务器对 pass 命令的响应
		m_pDlg->Disp(S_RECEIVE);
		//发送 stat 命令,请求服务器返回信箱中
		//邮件的数量和所占空间的大小
		s.Format("stat%c%c",13,10);
		Send((LPCSTR)s,s.GetLength());
		state=STAT; 
		break;

	case STAT:
	{
		string s1;
		str.seekg(0);  //将字符流的当前指针置为0
		str>>s1>>numMsg>>sizeMsg; //获得数量和大小
		flush(str);
		m_pDlg->Disp(S_GETNUM);
		m_pDlg->Disp(S_GETSIZE);
		if(numMsg>0) //如果有邮件,则发送RETR获得邮件信息
		{
			retrMsg=1;        //要取第一封信
			MESSAGEPROP prop; //准备存放信件的地方
			prop.msgSize=0;   //成员置初值
			prop.retrSize=0;
			prop.text="";
			msgs.push_back(prop); //压入向量表
			s.Format("retr 1%c%c",13,10);
			Send((LPCSTR)s,s.GetLength()); 
			state=RETR;
		}
		else //如果没有邮件,则断开
		{
			error="No new messages\r\n";
			Close();
		}
	}
	break;

	case RETR:
	{
		//显示取回来的信件文本

s.Format("numMsg= %d  retrMsg =%d",numMsg,retrMsg);	
m_pDlg->m_Info+=s;
s.Format("信件号%d: ,信件大小%d, 信件内容: %s   信件结束%c%c",
		 retrMsg-1,lastMsg.GetLength(),lastMsg,13,10);
m_pDlg->m_Info+=s;
m_pDlg->UpdateData(FALSE);		
				
		
				




		m_pDlg->Disp(S_RECEIVE);
		//一封信的内容可能多次才能接受回来,但是对于一封信,第一次
		//接收到数据的时候,对应向量结构的msgSize成员变量为0
		//if(msgs[retrMsg-1].msgSize==0) 
		//{
//			string temp;
//			str.seekg(0);
			//将该信件的大小存放到成员变量中
//			str>>temp>>msgs[retrMsg-1].msgSize; 
//		}
		//ix=lastMsg.Find("\r\n.\r\n");
		//if (ix == -1)
		//{
		//	msgs[retrMsg-1].text+=lastMsg;
		//	msgs[retrMsg-1].retrSize+=lastMsg.GetLength();
		//} else  {
		//	temp1=lastMsg.Left(ix+5);
		//	temp2=lastMsg.Right(lastMsg.GetLength()-ix-5);
		//	msgs[retrMsg-1].text+=temp1;
		//	msgs[retrMsg-1].retrSize +=temp1.GetLength();
		//}


		//将数据追加保存到text成员变量中
		msgs[retrMsg-1].text+=lastMsg; 
		//将数据大小累加到retrSize成员变量中,代表已经取回来的数量
		msgs[retrMsg-1].retrSize+=lastMsg.GetLength();
		//判断是否获得了这封信的所有数据
		//if(msgs[retrMsg-1].retrSize>=msgs[retrMsg-1].msgSize)
		//{  //检查是否有其他邮件
	
		ix=lastMsg.Find("\r\n.\r\n");
		if (ix != -1)	//找到了这封信的结尾
		{	
			//检查是否有其他邮件
			if(retrMsg<numMsg) //如果还有,则继续发送retr命令
			{
				MESSAGEPROP prop;
				prop.msgSize=0;
				prop.retrSize=0;
				prop.text="";
				msgs.push_back(prop);
				retrMsg++;
				//发retr命令取下一封信
				s.Format("retr %d%c%c",retrMsg,13,10);
				Send((LPCSTR)s,s.GetLength());
			}  else	{
				//如果全部信件接收完毕,判断是否要删除
				
				if(m_pDlg->m_bolDel && numMsg>0) 
				{
					state=DELE;
					delMsg=1;
					s.Format("dele %d%c%c",delMsg,13,10);
					Send((LPCSTR)s,s.GetLength());
				}  else {                      //否则退出
					state=ENDRETR;
					m_pDlg->Disp(S_ENDRETR);
					error="信件接收完,不删邮件,会话结束\r\n";
					s.Format("quit%c%c",13,10);
					Send((LPCSTR)s,s.GetLength());
					Close();

					for(int i=0;i<retrMsg;i++)
					{
						s.Format("%d:  %s",i,GetMsgSubject(i));
			//m_pDlg->m_Info+=s;

						m_pDlg->m_ctrList.AddString(s);
				//		m_pDlg->m_ctrList.AddString((LPCSTR)GetMsgSubject(i));
					}
			//m_pDlg->UpdateData(FALSE);
					m_pDlg->m_ctrList.SetCurSel(0);
				}
			}
		}  //DEBUG 
		//}
	}
	break;

	case DELE:
	{
		//删除剩余邮件
		if(delMsg<numMsg)
		{
			delMsg++;
			s.Format("dele %d%c%c",delMsg,13,10);
			Send((LPCSTR)s,s.GetLength());
		}
		else //如果已经删除完毕
		{
			m_pDlg->Disp(S_ENDRETR);
			state=GOON;
			error="Deleted all messages\r\n";
			s.Format("quit%c%c",13,10);
			Send((LPCSTR)s,s.GetLength());
			Close();
		}
	}
	break;
	
	case GOON:
	
	default:
		m_pDlg->Disp(S_RECEIVE);
		break;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -