약 6000 페이지의 웹 사이트에서 데이터를 가져와야합니다. 몇 가지 조사를 한 후에, 나는 WinHTTP를 한방 먹이기로 결정했다. 나는이 일을 할 수 있었지만 일을 동 기적으로하고 있었기 때문에 완료하는 데 시간이 걸렸다. WinHTTP를 비동기 적으로 사용하려고 시도하고 있지만로드 블록을 쳤습니다. 몇 가지 자습서와 예제를 검색했지만 MSDN 설명서 만 찾을 수있었습니다. 이는 내가하고있는 일에 지나치게 복잡하게 보입니다. 언급 한 바와 같이, 나는 많은 자원을 찾을 수 없습니다, 그래서 내가 나서서 그것을 촬영했다 :WinHTTP 여러 비동기 요청
void CALLBACK HttpCallback(HINTERNET hInternet, DWORD * dwContext, DWORD dwInternetStatus, void * lpvStatusInfo, DWORD dwStatusInfoLength)
{
switch (dwInternetStatus)
{
default:
std::cout << dwInternetStatus << "\n";
break;
case WINHTTP_CALLBACK_STATUS_HANDLE_CREATED:
std::cout << "Handle created.\n";
theRequest = 1;
break;
case WINHTTP_CALLBACK_STATUS_REQUEST_SENT:
std::cout << "Request sent.\n";
theRequest = 2;
break;
case WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED:
std::cout << "Response received.\n";
theRequest = 3;
break;
}
}
참고 :
다음std::string theSource = "";
char * httpBuffer;
DWORD dwSize = 1;
DWORD dwRecv = 1;
HINTERNET hOpen =
WinHttpOpen
(
L"Example Agent",
WINHTTP_ACCESS_TYPE_NO_PROXY,
NULL,
NULL,
WINHTTP_FLAG_ASYNC
);
WINHTTP_STATUS_CALLBACK theCallback =
WinHttpSetStatusCallback
(
hOpen,
(WINHTTP_STATUS_CALLBACK) HttpCallback,
WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS,
NULL
);
HINTERNET hConnect =
WinHttpConnect
(
hOpen,
L"example.org",
INTERNET_DEFAULT_HTTPS_PORT,
0
);
HINTERNET hRequest = NULL;
BOOL allComplete = false;
int theRequest = 1;
while (!allComplete)
{
if (theRequest == 1)
{
hRequest = WinHttpOpenRequest
(
hConnect,
L"GET",
L"example.html",
0,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE
);
WinHttpSendRequest
(
hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0,
WINHTTP_NO_REQUEST_DATA,
0,
0,
0
);
}
else if (theRequest == 2)
{
WinHttpReceiveResponse(hRequest, NULL);
}
else if (theRequest == 3)
{
WinHttpQueryHeaders
(
hRequest,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
NULL,
&dwSize,
WINHTTP_NO_HEADER_INDEX
);
WCHAR * headerBuffer = new WCHAR[dwSize/sizeof(WCHAR)];
WinHttpQueryHeaders
(
hRequest,
WINHTTP_QUERY_RAW_HEADERS_CRLF,
WINHTTP_HEADER_NAME_BY_INDEX,
headerBuffer,
&dwSize,
WINHTTP_NO_HEADER_INDEX
);
delete [] headerBuffer;
dwSize = 1;
while (dwSize > 0)
{
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
break;
}
httpBuffer = new char[dwSize + 1];
ZeroMemory(httpBuffer, dwSize + 1);
if (!WinHttpReadData(hRequest, httpBuffer, dwSize, &dwRecv))
{
std::cout << "WinHttpReadData() - Error Code: " << GetLastError() << "\n";
}
else
{
theSource = theSource + httpBuffer;
}
delete [] httpBuffer;
// Parse the source for the data I'm looking for.
break;
}
}
내 콜백 함수이다 나는 단지이 부분을 제공 한을 그것은 내 질문/문제에 관련된 부분이기 때문에 내 코드의. 변수 선언이 누락되면 사과드립니다.
위 코드는 저에게 효과적이며 실제로 원하는 정보를 얻지 만 단일 페이지에 대해서만 제공됩니다. 이 시점에 이르면이 방법으로 여러 요청을 할 때 수행 할 작업에 대해 알지 못한다는 사실을 깨달았습니다. 다시 말하지만 MSDN 기사 외에 검색이 많이 이루어지지 않았습니다. MSDN 기사는 한 번에 여러 요청을하는 예제가 아닙니다. 또한, while 루프는/etc/send를 열기 위해 사용하고 있습니다. theRequest의 값에 기반한 요청은 이것을하는 끔찍한 방법처럼 보입니다. 내 코드를 개선하기 위해 다른 조언을 주시면 감사하겠습니다.
일반적으로 다음은 내 문제 요약입니다. WinHTTP를 비동기 적으로 사용하여 약 6000 건의 GET 요청을 만들어야합니다. 필자는 WinHTTP를 처음 사용하기 때문에이 작업을 수행하는 방법을 완전히 알지 못하므로 여러 비동기 요청을 처리하는 가장 기본적인 (또는 가능한 효율적인) 방법을 찾고 있습니다.
[비동기 WinHTTP] (http://msdn.microsoft.com/en-us/magazine/cc716528.aspx) MSDN 문서를 보았습니까? 그리고이 단일 스레드, 멀티 소켓 및 이해하기 쉬운 [Perl API'HTTP :: Async'] (https://metacpan.org/module/HTTP::Async)는 진행 방법에 대한 영감을 줄 수 있습니다. – Lumi