私は最近、完全に動作するWinInetプログラムをWinHTTPに移植しました。WinHTTPがnullバイトをダウンロードしていますか、結果バッファを正しくコピーしていませんか?
bool Get(Url url, std::vector<char>& data, ProgressCallbackFunction progressCallback = nullptr) throw()
{
long cl = -1;
DWORD clSize = sizeof(cl);
DWORD readCount = 0;
DWORD totalReadCount = 0;
DWORD availableBytes = 0;
std::vector<char> buf;
if (_session != NULL)
throw std::exception("Concurrent sessions are not supported");
_session = ::WinHttpOpen(_userAgent.c_str(), WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, NULL);
auto connection = ::WinHttpConnect(_session, url.HostName.c_str(), url.Port, 0);
auto request = ::WinHttpOpenRequest(connection, TEXT("GET"), url.GetPathAndQuery().c_str(), NULL, NULL, NULL, WINHTTP_FLAG_REFRESH);
if (request == NULL)
{
_lastError = ::GetLastError();
::WinHttpCloseHandle(_session);
_session = NULL;
return false;
}
auto sendRequest = ::WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, NULL, WINHTTP_NO_REQUEST_DATA, NULL, NULL, NULL);
if (sendRequest == FALSE)
{
_lastError = ::GetLastError();
::WinHttpCloseHandle(request);
::WinHttpCloseHandle(_session);
_session = NULL;
return false;
}
if (::WinHttpReceiveResponse(request, NULL))
{
if (progressCallback != nullptr && progressCallback != NULL)
{
if (!::WinHttpQueryHeaders(request, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, reinterpret_cast<LPVOID>(&cl), &clSize, 0))
{
cl = -1;
}
}
while (::WinHttpQueryDataAvailable(request, &availableBytes))
{
if (availableBytes)
{
buf.resize(availableBytes + 1);
auto hasRead = ::WinHttpReadData(request, &buf[0], availableBytes, &readCount);
totalReadCount += readCount;
data.insert(data.end(), buf.begin(), buf.begin() + readCount);
buf.clear();
if (progressCallback != nullptr && progressCallback != NULL)
{
progressCallback(totalReadCount, cl, getProgress(totalReadCount, cl));
}
}
else
break;
}
}
else
{
_lastError = ::GetLastError();
::WinHttpCloseHandle(request);
::WinHttpCloseHandle(_session);
_session = NULL;
return false;
}
::WinHttpCloseHandle(request);
::WinHttpCloseHandle(_session);
_session = NULL;
return true;
}
コードは、それが要求されたURLをダウンロードすることでに動作します:ここで私はコードを一行にして全体をGETリクエストをラップするために書いた機能です。この問題は、サーバーがContent-Lengthヘッダーを返さないときに発生します(これはで、ほとんどの場合です)。コードは引き続きすべてのデータをダウンロードしますが、文字列に変換すると埋め込まれたnullバイトがあります。
上記のコードは、このように呼ばれる:
Url url(TEXT("http://msdn.microsoft.com/en-us/site/aa384376"));
Client wc;
std::vector<char> results;
wc.Get(url, results);
StdString html(results.begin(), results.end());
StdOut << html << endl;
StdStringは<TCHAR>とのbasic_string ::のtypedef STDであり、STDOUTはUNICODEが定義されている場合に応じて、COUT又はwcoutを使用するマクロです。
nullが埋め込まれているため、すべての応答がコンソールに表示されるわけではありません。デバッグをオフにしてコードを実行したときに表示される出力can be viewed here(行の区切りは、単にテキストが自分のコンソールにラップされていることに注意してください)。最初のヌルは最後に "__in"の直後に表示され、 "Press any key to continue。..."という出力が表示されます。ここでは、出力のスクリーンキャップだ:
ここでヌルが閲覧可能な何の関係で表示される場所を正確に示すHTML変数の値のテキストビジュアライザ画面のキャップです:
どこかに何か悪いコピーをしているのですか、私が気付いていないWinHTTPのニュアンスがありますか?
動作を再現する例はありますか?私はあなたのコードをコピーし、そのmsdnページを試して、埋め込まれたnullがなかった。 – Luke
次のリンクを含むように編集: http://pastebin.com/aEH9GzDE http://i.imgur.com/vRmNL.png http://i.imgur.com/eu8rH.png – jvstech