WinInet:如何使用 C++ 发送多个 http get 请求
WinInet : How to send multiple http get request with C++
我正在尝试编写一个从远程服务器下载一些东西的程序,
#include <iostream>
#include <string>
#include <Windows.h>
#include <WinInet.h>
#pragma comment(lib,"wininet.lib")
using namespace std;
string Get(){
DWORD size = 0;
DWORD wrt;
string msg = "";
HINTERNET io=InternetOpen("Downloader",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
HINTERNET ic=InternetConnect(io,"192.168.1.15",8080,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
HINTERNET hreq=HttpOpenRequest(ic,NULL,"/cgi-bin/cmd.py","HTTP/1.0",NULL,NULL,0,0);
HttpSendRequest(hreq,NULL,0,NULL,0);
InternetQueryDataAvailable(hreq,&size,0,0);
char* buffer = new char[size+1];
memset(buffer,0,size+1);
InternetReadFile(hreq,buffer,size,&wrt);
msg += buffer;
free(buffer);
InternetCloseHandle(io);
InternetCloseHandle(ic);
InternetCloseHandle(hreq);
return msg;
}
int main(){
while(TRUE){
string msg=Get();
if(msg.length()>1){
cout<<msg<<endl;
}
Sleep(2000);
}
return 0;
}
在另一端(在服务器上)我 运行 一个 python CGI 脚本,用于发送文本。
问题是程序只发送一次 GET 请求,即使存在循环并且 msg.length() 等于 0 ,在另一侧我可以看到我只收到一个 GET 请求。
有人可以解决我的问题,或者任何想法....
您需要为每个 WinInet API 调用添加错误处理。
您还需要循环 InternetReadFile()
,因为可能需要多次读取才能收到完整的响应。并且在将每个缓冲区附加到 std::string
.
时,您需要考虑实际读取的字节数
试试像这样的东西:
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
#pragma comment(lib, "wininet.lib")
struct sHINTERNET
{
HINTERNET hInet;
sHINTERNET(HINTERNET AInet = NULL) : hInet(AInet) {}
~sHINTERNET() { InternetCloseHandle(hInet); }
operator HINTERNET() { return hInet; }
bool operator!() const { return !hInet; }
}
void WinInetError(const char *FuncName)
{
DWORD dwErr = GetLastError();
std::ostringstream oss;
oss << FuncName << " failed!";
if (dwErr != ERROR_INTERNET_EXTENDED_ERROR)
oss << " Error: " << dwErr;
else
{
DWORD dwLen = 0;
InternetGetLastResponseInfo(&dwErr, NULL, &dwLen);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::basic_string<TCHAR> msg;
++dwLen;
msg.resize(dwLen);
if (InternetGetLastResponseInfo(&dwErr, &msg[0], &dwLen))
{
msg.resize(dwLen);
oss << " Error: " << msg;
}
}
}
throw std::runtime_error(oss.str());
}
std::string Download()
{
sHINTERNET io = InternetOpen("Downloader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!io)
WinInetError("InternetOpen");
sHINTERNET ic = InternetConnect(io, "192.168.1.15", 8080, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (!ic)
WinInetError("InternetConnect");
sHINTERNET hreq = HttpOpenRequest(ic, NULL, "/cgi-bin/cmd.py", "HTTP/1.0", NULL, NULL, 0, 0);
if (!hreq)
WinInetError("HttpOpenRequest");
if (!HttpSendRequest(hreq, NULL, 0, NULL, 0))
WinInetError("HttpSendRequest");
std::string data;
char buffer[1024];
DWORD wrt;
do
{
if (!InternetReadFile(hreq, buffer, sizeof(buffer), &wrt))
WinInetError("InternetReadFile");
if (wrt == 0)
break;
data.append(buffer, wrt);
}
while (true);
return data;
}
int main()
{
while (true)
{
try
{
std::string data = Download();
std::cout << data << std::endl;
}
catch (const std::exception &e)
{
std::cerr << "Error! " << e.what() << std::endl;
}
Sleep(2000);
}
return 0;
}
我正在尝试编写一个从远程服务器下载一些东西的程序,
#include <iostream>
#include <string>
#include <Windows.h>
#include <WinInet.h>
#pragma comment(lib,"wininet.lib")
using namespace std;
string Get(){
DWORD size = 0;
DWORD wrt;
string msg = "";
HINTERNET io=InternetOpen("Downloader",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
HINTERNET ic=InternetConnect(io,"192.168.1.15",8080,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
HINTERNET hreq=HttpOpenRequest(ic,NULL,"/cgi-bin/cmd.py","HTTP/1.0",NULL,NULL,0,0);
HttpSendRequest(hreq,NULL,0,NULL,0);
InternetQueryDataAvailable(hreq,&size,0,0);
char* buffer = new char[size+1];
memset(buffer,0,size+1);
InternetReadFile(hreq,buffer,size,&wrt);
msg += buffer;
free(buffer);
InternetCloseHandle(io);
InternetCloseHandle(ic);
InternetCloseHandle(hreq);
return msg;
}
int main(){
while(TRUE){
string msg=Get();
if(msg.length()>1){
cout<<msg<<endl;
}
Sleep(2000);
}
return 0;
}
在另一端(在服务器上)我 运行 一个 python CGI 脚本,用于发送文本。 问题是程序只发送一次 GET 请求,即使存在循环并且 msg.length() 等于 0 ,在另一侧我可以看到我只收到一个 GET 请求。 有人可以解决我的问题,或者任何想法....
您需要为每个 WinInet API 调用添加错误处理。
您还需要循环 InternetReadFile()
,因为可能需要多次读取才能收到完整的响应。并且在将每个缓冲区附加到 std::string
.
试试像这样的东西:
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
#pragma comment(lib, "wininet.lib")
struct sHINTERNET
{
HINTERNET hInet;
sHINTERNET(HINTERNET AInet = NULL) : hInet(AInet) {}
~sHINTERNET() { InternetCloseHandle(hInet); }
operator HINTERNET() { return hInet; }
bool operator!() const { return !hInet; }
}
void WinInetError(const char *FuncName)
{
DWORD dwErr = GetLastError();
std::ostringstream oss;
oss << FuncName << " failed!";
if (dwErr != ERROR_INTERNET_EXTENDED_ERROR)
oss << " Error: " << dwErr;
else
{
DWORD dwLen = 0;
InternetGetLastResponseInfo(&dwErr, NULL, &dwLen);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
std::basic_string<TCHAR> msg;
++dwLen;
msg.resize(dwLen);
if (InternetGetLastResponseInfo(&dwErr, &msg[0], &dwLen))
{
msg.resize(dwLen);
oss << " Error: " << msg;
}
}
}
throw std::runtime_error(oss.str());
}
std::string Download()
{
sHINTERNET io = InternetOpen("Downloader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!io)
WinInetError("InternetOpen");
sHINTERNET ic = InternetConnect(io, "192.168.1.15", 8080, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
if (!ic)
WinInetError("InternetConnect");
sHINTERNET hreq = HttpOpenRequest(ic, NULL, "/cgi-bin/cmd.py", "HTTP/1.0", NULL, NULL, 0, 0);
if (!hreq)
WinInetError("HttpOpenRequest");
if (!HttpSendRequest(hreq, NULL, 0, NULL, 0))
WinInetError("HttpSendRequest");
std::string data;
char buffer[1024];
DWORD wrt;
do
{
if (!InternetReadFile(hreq, buffer, sizeof(buffer), &wrt))
WinInetError("InternetReadFile");
if (wrt == 0)
break;
data.append(buffer, wrt);
}
while (true);
return data;
}
int main()
{
while (true)
{
try
{
std::string data = Download();
std::cout << data << std::endl;
}
catch (const std::exception &e)
{
std::cerr << "Error! " << e.what() << std::endl;
}
Sleep(2000);
}
return 0;
}