wininet是一个非常恶心的东西。。socket才是王道。。

华亭真人 2009-07-24 04:32:37
对比下代码:





STDMETHODIMP Cweb::Send(VARIANT server, VARIANT header, VARIANT *ret)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())

// TODO: Add your implementation code here

WORD wVersionRequested;
WSADATA wsaData;
int err;
char* str=_com_util::ConvertBSTRToString(server.bstrVal);
char* head=_com_util::ConvertBSTRToString(header.bstrVal);
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( 0 != err ) //检查Socket初始化是否成功
{
ret->vt=VT_BSTR;
ret->bstrVal=SysAllocString(L"Socket2.0初始化失败,Exit!");
return 0;
}

int sock,timeout;
char *hosttest;
sockaddr_in addr_recFrom;
sockaddr *temp_sockaddr;
hostent *test;

sock=socket(AF_INET,SOCK_STREAM,0);

test=gethostbyname(str);
hosttest=inet_ntoa(*((struct in_addr *)test->h_addr));
memset(&addr_recFrom,0,sizeof(addr_recFrom));
addr_recFrom.sin_family = AF_INET;
addr_recFrom.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)test->h_addr)));
addr_recFrom.sin_port = htons(80);

int flag;
timeout=10;
setsockopt(sock,SOL_SOCKET,SOCK_STREAM,reinterpret_cast<char FAR *>(&timeout),sizeof(int));

temp_sockaddr=new sockaddr;
memset(temp_sockaddr,0,sizeof(temp_sockaddr));
temp_sockaddr=(struct sockaddr *)&addr_recFrom;
flag=connect(sock,(struct sockaddr *)&addr_recFrom,sizeof(addr_recFrom));

send(sock, head, strlen(head), 0);
char text[1024]="";

CString ss;
while ( recv(sock, text, 1024, 0) > 0)
{
CString s;
s.Format("%s",text);
ss+= s;

memset(text,0,1024);
}

ret->vt=VT_BSTR;
ret->bstrVal=ss.AllocSysString();
closesocket(sock);
WSACleanup();

return S_OK;
}





#include<wininet.h>
#include<process.h>
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
#pragma comment(lib,"wininet.lib")

#include<stdlib.h>
#define UNICODE
#define _UNICODE
#include<crtdbg.h>
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
#define TIMEOUT 3000

void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen);

CString ToString (DWORD i)
{
CString str;
str.Format("%d",i);
return str;

}
HINTERNET hSession;
HINTERNET hFile;
HANDLE hComplete;
HANDLE CloseFile;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
CoInitialize(0);


_ConnectionPtr pConnection;
_RecordsetPtr pRecordset;
if(pConnection.CreateInstance(__uuidof(Connection))!=S_OK)
{
return false;
}
CString strConnect;
CString strDBFile="1.mdb";
strConnect.Format(_T("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s"),strDBFile);
if(pConnection->Open(_bstr_t( strConnect),"", "", 0)==S_OK)
{
// _RecordsetPtr pRecordset;
if(pRecordset.CreateInstance(__uuidof(Recordset)) != S_OK)
{
pConnection->Close();
return false;
}
CString strSql;
strSql="select * from db where flag=false order by id";
HRESULT hr=pRecordset->Open(_bstr_t(strSql),pConnection.GetInterfacePtr(), adOpenStatic,
adLockOptimistic,
adCmdText);



if(hr!=S_OK)
{
pConnection->Close();
return false;
}

}

hComplete=CreateEvent(NULL,FALSE,FALSE,NULL);

CloseFile=CreateEvent(NULL,FALSE,FALSE,NULL);
hSession = InternetOpen(NULL,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL,
NULL,
INTERNET_FLAG_ASYNC);

if (InternetSetStatusCallback(hSession,
(INTERNET_STATUS_CALLBACK)&Callback) == INTERNET_INVALID_STATUS_CALLBACK)
{

cout<<"回调函数注册失败"<<endl;
return false;
}
if(!pRecordset->BOF)
{
pRecordset->MoveFirst();

while(!pRecordset->adoEOF)
{
ResetEvent(hComplete);
ResetEvent(CloseFile);
CString url=(LPCSTR)(_bstr_t)pRecordset->Fields->GetItem("url")->Value;
ULONG l=INTERNET_CONNECTION_LAN;

printf("%s\n",url.GetBuffer(0));
url.ReleaseBuffer();
hFile =InternetOpenUrl(hSession,url,NULL,0,INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD,1);
if(WaitForSingleObject(hComplete,TIMEOUT)==WAIT_TIMEOUT)
{
printf("超时\n");
}

else
{
CString str;
bool bAllDone=false;
do
{

char lpReadBuff[512];
INTERNET_BUFFERS InetBuff;
bool outed=false;
ResetEvent(hComplete);
memset(lpReadBuff,0,512);
FillMemory(&InetBuff, sizeof(InetBuff), 0);
InetBuff.dwStructSize = sizeof(InetBuff);
InetBuff.lpvBuffer = lpReadBuff;
InetBuff.dwBufferLength = sizeof(lpReadBuff) - 1;
BOOL bOk=InternetReadFileEx(hFile,
&InetBuff,
IRF_ASYNC, 1);
if(!bOk&&GetLastError()==ERROR_IO_PENDING)
{

if(WaitForSingleObject(hComplete,2000)==WAIT_TIMEOUT)
{
printf("error\n");
}

}
// cout<<lpReadBuff<<endl;
CString s;
s.Format("%s",lpReadBuff);
if(s=="")
break;
str+=s;

lpReadBuff[InetBuff.dwBufferLength] = 0;

// cout<<InetBuff.dwBufferLength <<endl;

if (InetBuff.dwBufferLength == 0)
{

bAllDone = TRUE;
}

}while(bAllDone==false);


pRecordset->PutCollect("result",_variant_t(str));
COleDateTime time=COleDateTime::GetCurrentTime();
pRecordset->PutCollect("times2",_variant_t(time));
pRecordset->PutCollect("flag",_variant_t(true));
pRecordset->Update();
}


InternetCloseHandle(hFile);
hFile=NULL;

WaitForSingleObject(CloseFile,2000);
// cout<<GetLastError()<<endl;


pRecordset->MoveNext();

}
}

if(pConnection)
{
pConnection->Close();
pConnection.Release();
}
if(pRecordset)
{
pRecordset.Release();
}


}
InternetSetStatusCallback(hSession,NULL);
InternetCloseHandle(hSession);


CoUninitialize();

system("pause");
return nRetCode;
}



void __stdcall Callback(HINTERNET hInternet,
DWORD dwContext,
DWORD dwInternetStatus,
LPVOID lpStatusInfo,
DWORD dwStatusInfoLen)
{

// cout<<dwInternetStatus<<endl;
switch(dwInternetStatus)
{
case INTERNET_STATUS_RESOLVING_NAME:

case INTERNET_STATUS_HANDLE_CREATED:
{
INTERNET_ASYNC_RESULT* res = (INTERNET_ASYNC_RESULT*)lpStatusInfo;
hFile = (HINTERNET)(res->dwResult);
}
break;
case INTERNET_STATUS_REQUEST_COMPLETE:


while(!SetEvent(hComplete))
{
printf("%d",GetLastError());
}

break;
case INTERNET_STATUS_HANDLE_CLOSING:

while(!SetEvent(CloseFile))
{
printf("%d",GetLastError());
}
break;
case INTERNET_STATUS_CONNECTION_CLOSED:


break;

}
return;



}




程序清晰明了,虽然解析起来麻烦了些,但可以随意控制header和cookie,而且socket不只用于Http.更加灵活强大。。。
想起学习wininet的痛苦。。不堪回首啊


朋友们可不要像我一样走弯路啊,小的应用wininet方便易用,但它掩盖了本质,让我们只能看到有限的东西。
...全文
1197 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zoulie 2009-07-24
  • 打赏
  • 举报
回复
存在即合理。。
华亭真人 2009-07-24
  • 打赏
  • 举报
回复
自动充值平台,从(XX)网到(XX)网
rendao0563 2009-07-24
  • 打赏
  • 举报
回复
比如现在,上百个用户通过我的服务器,去登录另一个网站,请教一个方案,如何用wininet模拟提交,并且保证他们的session不会混乱???

你的服务器是代理服务器?
wangk 2009-07-24
  • 打赏
  • 举报
回复
代理服务端用wininet?
你不会期望微软的一个库搞定你所有的应用需求吧?

绘图用GDI就好了,GDI+拿来干什么用,DirectX一边休息去吧

微软的每一个函数库有其特定需求产生,不是随意出来的,也不能包办一切。
华亭真人 2009-07-24
  • 打赏
  • 举报
回复
原来我的设想也是用wininet ,但asp后台必然要调用COM访问127。0。0。1将账号密码传给服务器,服务器负责登录目标网站,然后进行各种操作,然后用一个链表来维护各用户的cookie,所以全部改成socket了
华亭真人 2009-07-24
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 alfwolf 的回复:]
请不要随意轻视别人的东西,尤其是已经发布并且广为应用的东西。
或许只是你不了解而已。

[/Quote]

wininet用了大概有一年,曾经写过下载3KW张图片的多线程网络爬虫,几十个自动处理系统,自问水平还没到不了解的地步。
MS封装wininet当然有原因,但并不意味着它一定适用于你的项目,
HTTP无非是一个协议,没什么深奥的,能sniffer 出来的也一定可以模拟,

比如现在,上百个用户通过我的服务器,去登录另一个网站,请教一个方案,如何用wininet模拟提交,并且保证他们的session不会混乱???

aa3000 2009-07-24
  • 打赏
  • 举报
回复
还有代理的问题,当然WININET不支持 socks5 代理,不过用 socket 处理代理的问题也是比较麻烦的。虽然有开源库
alfwolf 2009-07-24
  • 打赏
  • 举报
回复
请不要随意轻视别人的东西,尤其是已经发布并且广为应用的东西。
或许只是你不了解而已。
pady_pady 2009-07-24
  • 打赏
  • 举报
回复
ssl 之类的,有认证的
华亭真人 2009-07-24
  • 打赏
  • 举报
回复
LS 讲的我有点不太明白。不都是发送数据包吗,什么情况下网站会不认?
pady_pady 2009-07-24
  • 打赏
  • 举报
回复
顶下
rendao0563 2009-07-24
  • 打赏
  • 举报
回复
区别在于你写的可能有些网站不认。socket直接处理http有很多细节。所有微软才封了一层。
ouyh12345 2009-07-24
  • 打赏
  • 举报
回复
我也更喜欢用socket
快乐鹦鹉 2009-07-24
  • 打赏
  • 举报
回复
。。。。。。

18,356

社区成员

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

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