用WinINet登录网站时遇到的问题

SolidRabbit 2008-07-30 07:43:35
MSDN里说HttpSendRequest的lpOptional参数指向的内容会紧接着协议头发送给服务器,而我写了程序用抓包工具发现附加的数据被直接接在协议头上作为一个包发出去了。而用IE登录时,协议头和附加数据是两个包,我的程序发的包人家根本找不到帐号和密码信息(我多冤枉啊,明明有的。我的数据和IE所有数据一模一样,唯一区别就是它的包被分成了两个)。
我翻了半天的MSDN,Google了半天,一直没找到解决方法。 还是说这个功能不是用HttpSendRequest实现的?
大侠帮帮忙

代码:
#include <iostream>
#include <windows.h>
#include <wininet.h>
#pragma comment(lib, "wininet.lib")

#define _DEBUGGING

using namespace std;

HINTERNET hSession, hConnection, hRequest;

void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
sprintf((char *)lpDisplayBuf, "%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}

DWORD ReadResourses(LPVOID &lpvBuffer)
{//读取资源,并返回资源文件长度
DWORD dwBufferLength = 1024;
DWORD dwReaded = 0;
DWORD nCount = 0;
LPVOID lpvBuffTemp = NULL;
LPVOID lpvBuff = NULL;

lpvBuffer = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, dwBufferLength + 1);//给'\0'留个位子
do
{//循环读取,直到读完
InternetReadFile(hRequest, lpvBuffer, dwBufferLength, &dwReaded);
*((BYTE *)lpvBuffer+dwReaded) = '\0';
nCount++;
//分配内存
lpvBuffTemp = lpvBuff;
lpvBuff = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof (BYTE)*(dwBufferLength*nCount + 1));
if (NULL != lpvBuffTemp)
{
memcpy(lpvBuff, lpvBuffTemp, dwBufferLength*(nCount-1) + 1);
}
strcat((char *)lpvBuff, (char *)lpvBuffer);
} while (0 != dwReaded);
GlobalFree(lpvBuffTemp); lpvBuffTemp = NULL;
GlobalFree(lpvBuffer); lpvBuffer = NULL;
lpvBuffer = lpvBuff; lpvBuff = NULL;

return dwBufferLength*nCount + 1;
}

BOOL ConnectTo(TCHAR hostname[])
{//连接到服务器

//建立会话
hSession =InternetOpen("Mozilla/4.0",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
if (NULL == hSession)
{
ErrorExit("ConnectTo");
}

//建立连接
hConnection = InternetConnect( hSession, hostname, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
if (NULL == hConnection)
{
ErrorExit("ConnextTo");
}

return TRUE;
}

void QueryHeader(DWORD dwFlag)
{//查询报头
LPVOID lpvBuffer = NULL; //用于存储返回数据的内存
DWORD dwBufferLength = 1024; //lpvBuffer的内存大小

lpvBuffer = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof (BYTE)*dwBufferLength);
while (!HttpQueryInfo(hRequest, dwFlag, lpvBuffer, &dwBufferLength, NULL))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{//内存不够大,重新分配
GlobalFree(lpvBuffer);lpvBuffer = NULL;
lpvBuffer = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof (BYTE)*dwBufferLength);
}
else
{
ErrorExit("HttpQueryInfo");
}
}
*((BYTE *)lpvBuffer+dwBufferLength) = '\0';

cout<<(char *)lpvBuffer<<endl;
GlobalFree(lpvBuffer);lpvBuffer = NULL;
}

void main()
{
//登录PEDIY
/*LPCTSTR*/TCHAR lpreferer[] = "http://bbs.pediy.com/"; //参考
TCHAR host[] = "bbs.pediy.com"; //要访问的主机
LPCTSTR objectname = "login.php?do=login";//NULL; //要访问的资源,访问默认页面时可使用空串
LPCTSTR addtionheaders = "vb_login_username=Test&cookieuser=1&vb_login_password=&s=&do=login&vb_login_md5password=12341234&vb_login_md5password_utf=12341234"; //附加头

//登录XIAONEI
/*
/*LPCTSTR*/TCHAR lpreferer[] = "http://www.xiaonei.com/SysHome.do
"; //参考
TCHAR host[] = "login.xiaonei.com"; //要访问的主机
LPCTSTR objectname = "/Login.do";//NULL; //要访问的资源,访问默认页面时可使用空串
LPCTSTR addtionheaders = "email=1234567&password=7654321&origURL=http%3A%2F%2Fwww.xiaonei.com%2FSysHome.do&submit=%E7%99%BB%E5%BD%95"; //附加头
*/
TCHAR version[] = "HTTP/1.1"; //协议版本


TCHAR verb[] = "POST";//"GET"; //动作
LPCTSTR *accepttypes = NULL;

LPCTSTR headers ="\r\n\r\n";// NULL; //头,以"\r\n\r\n"结尾

LPVOID lpvBuffer = NULL; //用于存储返回数据的内存

ConnectTo(host);//连接到服务器

//建立请求
accepttypes = (LPCTSTR *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof (DWORD)*2); //数组里有两个指针
*accepttypes = (LPCTSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, 32);//字符串1
strcpy ((char *)(*accepttypes), "text/*");

hRequest = HttpOpenRequest(hConnection, verb, objectname, version, lpreferer, accepttypes, INTERNET_FLAG_KEEP_CONNECTION, 0);
if (NULL == hRequest)
{
ErrorExit("HttpOpenRequest");
}
//添加请求
if (!HttpAddRequestHeaders(hRequest, headers, -1, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE))
{
ErrorExit("HttpAddRequestHeaders");
}
//发送请求
if (!HttpSendRequest(hRequest, headers, strlen(headers), (LPVOID)addtionheaders, strlen(addtionheaders)))
{
ErrorExit("HttpSendRequest");
}

#ifdef _DEBUGGING
//查询请求的报头
cout<<"==请求=="<<endl;
QueryHeader(HTTP_QUERY_FLAG_REQUEST_HEADERS | HTTP_QUERY_RAW_HEADERS_CRLF);
//查询服务器返回的报头
cout<<"==返回=="<<endl;
QueryHeader(HTTP_QUERY_RAW_HEADERS_CRLF);
#endif

ReadResourses(lpvBuffer);
printf("%s", lpvBuffer);

GlobalFree(lpvBuffer); lpvBuffer = NULL;
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnection);
InternetCloseHandle(hSession);
}

发现登录看雪论坛可以,登录校内就不行了。用IE访问看雪这里请求头和登录信息是在一个包里的,访问IE请求头和登录信息是在两个包里,而且两个包是连续发出去的,不是等服务器有回应了才发第二个包的。而这个程序发出去的包是第一种情况的,所以到校内那边就用不了了~
这个问题怎么解决?是有一些设置我没打开,还是要用别的方法?

里面帐号密码部分由于众所周知的原因被我马赛克掉了,你可以换自己的帐号密码试
...全文
169 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
SolidRabbit 2008-07-31
  • 打赏
  • 举报
回复
我妄图通过HOOK send函数手动把那个包给拆成两个,结果却是是拆成两个了,但是那它紧接着又补了一个包,所以服务器仍然不让我登录上去……

救命啊……

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧