错误是发送还是接收?未发送完整消息或消息未正确解码


Is the error upon Sending or Receiving? Full message not sent or message not decoded properly

所以我将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。那么,错误会发生在哪里呢?是不是发送了整个post字符串,或者PHP脚本没有正确处理unicode?

您不发送所有字符。您还错误地指定了编码

wchar_t *s1 = L"abc";不是UTF-8编码的char *s2 = "abc";恰好是UTF-8编码的(这是UTF-8的一个很好的特性),但使用这种表示法,您只能使用拉丁字符。请参阅下面的示例。

_tcslen(frmdata)返回的是字符数,而不是字节数。如果定义Unicode,则字符串占用的字节数多于字符数。您的服务器需要UTF-8字节序列,但实际编码不是UTF-8。

关于如何在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