对比下代码: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 3000void __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方便易用,但它掩盖了本质,让我们只能看到有限的东西。

解决方案 »

  1.   

    区别在于你写的可能有些网站不认。socket直接处理http有很多细节。所有微软才封了一层。
      

  2.   

    还有代理的问题,当然WININET不支持 socks5 代理,不过用 socket 处理代理的问题也是比较麻烦的。虽然有开源库
      

  3.   


    wininet用了大概有一年,曾经写过下载3KW张图片的多线程网络爬虫,几十个自动处理系统,自问水平还没到不了解的地步。
    MS封装wininet当然有原因,但并不意味着它一定适用于你的项目,
    HTTP无非是一个协议,没什么深奥的,能sniffer 出来的也一定可以模拟,比如现在,上百个用户通过我的服务器,去登录另一个网站,请教一个方案,如何用wininet模拟提交,并且保证他们的session不会混乱???
      

  4.   

    原来我的设想也是用wininet ,但asp后台必然要调用COM访问127。0。0。1将账号密码传给服务器,服务器负责登录目标网站,然后进行各种操作,然后用一个链表来维护各用户的cookie,所以全部改成socket了
      

  5.   

    代理服务端用wininet?
    你不会期望微软的一个库搞定你所有的应用需求吧?绘图用GDI就好了,GDI+拿来干什么用,DirectX一边休息去吧微软的每一个函数库有其特定需求产生,不是随意出来的,也不能包办一切。
      

  6.   

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

  7.   

    自动充值平台,从(XX)网到(XX)网