是发送还是接收错误?未发送完整消息或未正确解码消息
Posted
技术标签:
【中文标题】是发送还是接收错误?未发送完整消息或未正确解码消息【英文标题】:Is the error upon Sending or Receiving? Full message not sent or message not decoded properly 【发布时间】:2016-07-25 02:14:37 【问题描述】:所以我将一些数据从我的 C++ 桌面应用程序发布到我的服务器(一个 php 脚本)。
并非所有发布数据都被服务器接收。你认为错误发生在哪里?在服务器端解码(UTF-8)还是在客户端传输?
C++ 代码:注意它的 Unicode。如果我发送 ASCII 脚本接收/解码整个帖子数据字符串:
static TCHAR hdrs[] =
_T("Content-Type: application/x-www-form-urlencoded; charset=UTF-8\0\0");
static TCHAR frmdata[] =
_T("name=John+Doe&auth=abc\0\0"); // use 2 null chars just incase
static LPSTR accept[2] = "*/*", NULL ;
HINTERNET hSession = InternetOpen(_T("MyAgent"),
INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
// error checking removed but none of these fail
HINTERNET hConnect = InternetConnect(hSession, _T("mydomain.com"),
INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
HINTERNET hRequest = HttpOpenRequest(hConnect, _T("POST"),
_T("upload.php"), NULL, NULL, (LPCWSTR*)&accept, INTERNET_FLAG_NO_CACHE_WRITE, 1);
HttpSendRequest(hRequest, hdrs, _tcslen(hdrs), frmdata, _tcslen(frmdata));
// The above function returns true and I query the response code and its HTTP 200 ok so sending is working
简单的 PHP 脚本:
$data = file_get_contents("php://input");
file_put_contents("post.txt", $data); // outputs "name=John+D" so its missing text
// To make things even more confusing
echo mb_detect_encoding($data); // outputs ASCII!!!???
奇怪的是,如果我以 ASCII 格式发送,脚本会接收/解码整个帖子数据
static char hdrs[] =
_T("Content-Type: application/x-www-form-urlencoded; charset=UTF-8\0\0");
static char frmdata[] =
_T("name=John+Doe&auth=abc\0\0");
static LPCSTR accept[2] = "*/*", NULL ;
...
HttpSendRequestA(hRequest, hdrs, strlen(hdrs), frmdata, strlen(frmdata));
// The above function returns true and I query the response code and its HTTP 200 ok so sending is working
使用 ASCII post.txt 包含 name=John+Doe&auth=abc
。那么错误会发生在哪里呢?是不是整个帖子字符串都被发送了,还是 PHP 脚本没有正确处理 unicode?p>
【问题讨论】:
_T("... charset=UTF-8");
- 只要你#define _UNICODE
,那就是谎言。您需要了解字符编码,以及这些通用文本映射是什么(请参阅Ansi- and Wide-character functions)。
@IInspectable 是的,这只是一个测试。即使没有指定字符集,它也会失败。
【参考方案1】:
您不会发送所有字符。您还错误地指定了编码。
wchar_t *s1 = L"abc";
不是 UTF-8 编码的
char *s2 = "abc";
恰好是 UTF-8 编码的(这是 UTF-8 的一个很好的属性),但是使用这种表示法,您只能使用拉丁字符。请参见下面的示例。
_tcslen(frmdata) 返回字符数,而不是字节数。如果您定义 Unicode,则字符串占用的字节数多于字符数。您的服务器需要 UTF-8 字节序列,但实际编码不是 UTF-8。
关于如何指定文字字符串encoding in C++ 11的几个例子
// Greek small letter tau
char const *tau8 = u8"\u03C4"; // UTF-8
char16_t tau16 = u'\u03C4'; // UTF-16
wchar_t tau32 = U'\U000003C4'; // UTF-32
【讨论】:
以上是关于是发送还是接收错误?未发送完整消息或未正确解码消息的主要内容,如果未能解决你的问题,请参考以下文章