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

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

【讨论】:

以上是关于是发送还是接收错误?未发送完整消息或未正确解码消息的主要内容,如果未能解决你的问题,请参考以下文章

Swift:解码从 GameKit 发送的消息

Firebase 消息:由于所需的 APNs SSL 证书已过期或未上传,无法向 iOS 设备发送消息

PHP IMAP 解码消息

Protobuf 和非阻塞消息发送/接收

UCWA:发送多条消息时出错

“错误:消息文件太大”是传出端还是接收端的限制? [关闭]