1、本机环境:
Windows XP SP3、ADSL
2、开发工具:
WildPackets OmniPeek V5.1.4
Visual C++ 6.0
IE6.0
FlexEdit V2.3.1871
如果觉得OmniPeek文件太大不方面下载的朋友,可以使用开源的简易抓包分析工具,先登录codeproject,再单击此处开始下载或邮件给我索取源码 (ningyusky@tom.com 或 koma0769@vip.qq.com)
注意:如果没有登录codeproject的话是无法下载的,你可以自行修改该工具源码,将每一步GET、POST等动作的数据全部记录于某文件,以便查看分析之.....
我就是如此,因为我的硬件配置不是很“主流”的,所以每次OmniPeek启动和新建工程时,电脑都快要死机.....
3、程序运行效果:
4、源码说明:
虽如此短短一百余行的代码,但我在debug下调试了三个多小时才解决了这里每一处存在或可能存在的错误,希望可以与大家交流共同探讨......
/************************************************************************/ /* 函数说明:模拟POST表单——登录新浪邮箱 /* 参 数:无 /* 返 回 值:无 /* By:Koma 2009.10.16 10:18 /************************************************************************/ void CSinaDlg::OnOK() { // TODO: Add extra validation here UpdateData(TRUE); if(m_strUser.IsEmpty()){ MessageBox("邮箱用户名不能为空","提示"); m_ctrUser.SetFocus(); return; } if(m_strUser.Find("@sina") < 1){ MessageBox("请先添加邮箱名的后缀,如@sina...","提示"); m_ctrUser.SetFocus(); return; } if(m_strPassword.IsEmpty()){ MessageBox("邮箱密码不能为空","提示"); m_ctrUser.SetFocus(); return; } char szAccept[] = "Accept: */*"; char szReferer[] = "Referer: http://mail.sina.com.cn//r/n"; CString szFormData = "domain=sina.cn&logintype=uid&u="+ m_strUser +"&domain=sina.com&psw="+ m_strPassword +"&btnloginfr"; HINTERNET hSession; HINTERNET hConnect; HINTERNET hRequest; BOOL bReturn = FALSE; // 之前使用Socket,现在使用Wininet相关API建立链接 hSession = InternetOpen("InetAll",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); hConnect = InternetConnect(hSession,"mail.sina.com.cn",INTERNET_DEFAULT_HTTP_PORT,NULL,NULL,INTERNET_SERVICE_HTTP,0,1); hRequest = HttpOpenRequest(hConnect,"POST","cgi-bin/login.cgi",NULL,"http://www.sina.com.cn",(LPCSTR *)&szAccept,INTERNET_FLAG_RELOAD,1); // 提交数据表单 LPVOID pBuf = (LPVOID)szFormData.GetBuffer(szFormData.GetLength()); bReturn = HttpSendRequest(hRequest,"Content-Type: application/x-www-form-urlencoded/r/n",-1,pBuf,szFormData.GetLength()); if(!bReturn) { MessageBox("发送Http请求失败!","提示",MB_ICONERROR | MB_OK); return; } char szRecvBuf[1024]; // 接受数据缓冲区 DWORD dwNumberOfBytesRead; // 服务器返回大小 DWORD dwRecvTotalSize=0; // 接受数据总大小 DWORD dwRecvBuffSize=0; // 接受数据buf的大小 CFile m_File; // 将返回数据写入文件 CString strTemp; // 临时消息框 m_File.Open("RecvData.tmp",CFile::modeWrite | CFile::modeCreate,NULL); memset(szRecvBuf,0,1024); do { // 开始读取数据 bReturn = InternetReadFile(hRequest,szRecvBuf,1024,&dwNumberOfBytesRead); if(!bReturn) { MessageBox("InternetReadFile Error !","提示",MB_ICONERROR | MB_OK); break; } // 统计接受数据的大小 szRecvBuf[dwNumberOfBytesRead] = '/0'; dwRecvTotalSize += dwNumberOfBytesRead; dwRecvBuffSize += strlen(szRecvBuf); // 将缓冲区写入文件 m_File.Write(szRecvBuf,strlen(szRecvBuf)); m_File.Flush(); } while(dwNumberOfBytesRead !=0); // 检查接受到的数据包是否完整 m_File.Close(); if(dwRecvTotalSize != dwRecvBuffSize) { MessageBox("接受数据时丢包,返回大小不一致!"); return ; } CString str=""; // 全部内容 CString strLine=""; // 单行内容 CStdioFile file; // 文件对象 if(!file.Open("RecvData.tmp",CFile::modeRead | CFile::typeText,NULL)) { CString strTemp; strTemp.Format("Open file error:%d",GetLastError()); MessageBox(strTemp); return; } // 按行读取tmp全部内容 while(file.ReadString(strLine)) { str = str + strLine; } file.Close(); wchar_t* pWChar = NULL; DWORD nLen1; // 将新浪网页UTF-8格式编码转换成Unicode nLen1 = MultiByteToWideChar(CP_UTF8,0,str,str.GetLength(),pWChar,0); pWChar = new wchar_t[nLen1 + 1]; memset(pWChar,0,(nLen1 + 1 ) * sizeof(wchar_t)); MultiByteToWideChar(CP_UTF8,0,str,str.GetLength(),pWChar,nLen1); char* pChar = NULL; DWORD nLen2; nLen2 = WideCharToMultiByte(CP_ACP,0,pWChar,nLen1,pChar,0,NULL,NULL); pChar = new char[nLen2 + 1]; memset(pChar,0, nLen2 + 1); WideCharToMultiByte(CP_ACP,0,pWChar,nLen1,pChar,nLen2,NULL,NULL); // 查找登录时服务器时返回的信息 str.Format("%s",pChar); if(str.Find("安全退出",0)>=1) { MessageBox("邮箱登录成功!","提示"); m_ctrUser.SetFocus(); } else { MessageBox("邮箱登录失败!","提示",MB_ICONERROR | MB_OK); m_ctrUser.SetFocus(); } // 删除临时文件、释放内存 DeleteFile("RecvData.tmp"); delete pChar; delete pWChar; }