无法从Web服务器读取utf-8缓冲区
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法从Web服务器读取utf-8缓冲区相关的知识,希望对你有一定的参考价值。
我正在用C ++编写一个简单的Web爬虫。
它连接到Web服务器并发送“GET”请求,然后它从Web服务器接收回复。
这是我用来执行此操作的代码段:
CHttpHeader reqHeader = websock.GenerateRequestHeader(url, nullptr);
dwResponse = websock.SendRequest(url, reqHeader, nullptr, nullptr);
if (dwResponse == 0) {
//::MessageBoxA(this->GetSafeHwnd(), "error to send http request", 0, 0);
return;
}
//char*strstr = "병맛메로나";
// Receive Response
const int bufferSize = 1024 * 1024 * 1;
char * buffer = new char[bufferSize * 10];
char *tbuffer = new char[bufferSize];
int recvLen = 0;
DWORD dwNextOffset = 0;
//setlocale(LC_ALL, "");
while (websock.HasMoreResponse()) {
recvLen = websock.Recv(tbuffer, bufferSize);
::memcpy(buffer + dwNextOffset, tbuffer, recvLen);
dwNextOffset+= recvLen;
}
服务器回复将被复制到buffer
,长度为dwNextOffset
。
每件事都可以正常连接到服务器并正确接收回复。但是,在某些情况下使用UTF-8编码的回复,我无法从缓冲区中读取html标记。这一切都是胡言乱语。
我想这是由于客户端/服务器操作系统的差异。因为我在Windows上,当Web服务器是IIS(很可能在Windows上运行)时,读取UTF-8编码字符没有问题。但是,在Apache的某些情况下,会出现此问题。
操作系统之间的UTF-8格式是否不同?
如果是这样,我可以正确转换为MBCS吗?
编辑:这是文件保存部分:
FILE* fp = nullptr;
::fopen_s(&fp, "result", "wb");
::fwrite(buffer, 1, dwOffset, fp);
::fclose(fp);
结果是......
HTTP/1.1 200 OK Date: Tue, 27 Feb 2018 12:19:19 GMT X-UA-Compatible: IE=10 Expires: Sat, 01, Jan 1970 22:00:00 GMT Pragma: no-cache Cache-Control: no-cache, no-store, must-revalidate P3P: CP="ALL DSP COR MON LAW IVDi HIS IVAi DELi SAMi OUR LEG PHY UNI ONL DEM STA INT NAV PUR FIN OTC GOV" Content-Type: text/html;charset=UTF-8 Content-Language: ko-KR Vary: Accept-Encoding Content-Encoding: gzip X-UA-Device-Type: pc Content-Length: 49043 Connection: close ? 醬??/影?-~퍏뙗*쿭돃?긥먉^...
编辑:Max Vollmer,你是对的。在请求中使用Accept-Encoding : identity
解决了一些问题。但还有另一个问题。
如果我使用此代码:
char *strstr = "병맛메로나";
std::string tstr(strstr);
tstr
工作正常。
但是,如果我把buffer
变成std::string
,它又会有胡言乱语。
std::string tstr(buffer);
为什么会这样?
你的第一个问题,压缩:
Content-Encoding: gzip
您的数据已压缩,您必须将其解压缩。见Content-Encoding。这样做有很多C ++库。
或者,您可以根据您的请求发送Accept-Encoding: identity
标头,因此服务器不会发送压缩数据。见Accept-Encoding。
你的第二个问题,编码:
如果缓冲区是UTF-8编码,你不能只做std::string tstr(buffer);
。首先,这根本不解码任何UTF-8字符。您甚至没有告诉它您的数据是UTF-8编码的,它应该如何知道?其次,任何需要超过8个字节的字符都不能用单个char
表示,而std :: string使用char
作为其字符,因此std::string
永远不能保存UTF-8编码数据的文本表示。
你可能会对char
究竟是什么感到困惑。它是一个8位大小的整数。
由于UTF-8使用多个字节对特殊字符进行编码,因此这些字符将存储在char数组中的多个字符中。当您使用该char数组创建一个std::string
时,它只会将每个char解释为一个字符,这是错误的。
您必须将UTF-8数据解码为多字节字符串,例如std::wstring
,或使用一些第三方库提供一些支持UTF-8开箱即用的字符串类。或者只是将数据写入文件并使用支持UTF-8的文本编辑器打开该文件,它应该自动检测编码。真的取决于你想要做什么。
这是将UTF-8编码数据转换为std::wstring
的简单方法:
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::wstring text = converter.from_bytes(buffer);
以上是关于无法从Web服务器读取utf-8缓冲区的主要内容,如果未能解决你的问题,请参考以下文章