你好亲爱的Stackoverflowers!
我的项目有问题,关于客户端-> 服务器通信。我想将数据从 C++ 程序传输到服务器。为此,我选择了 HTTP 作为通信协议,因为它很容易通过类似的 PHP 脚本在 web 服务器上进行处理。C++ 程序通过 HTTP POST 向服务器发送数据(或命令),服务器通过 PHP 脚本生成纯文本响应(Mime-Type text/plain)。生成的响应相对较短,包含简短的成功或失败消息,也许还有一点“有效负载”(全是纯文本)。
在我的开发机器(本地 Apache 服务器lampp)上,一切似乎都运行良好。但是,今天我尝试在实时网络服务器(运行 Apache + PHP + MySQL 的虚拟网络服务器服务)上移动服务器 PHP 脚本以进行测试,并且,有些东西停止了工作......
问题
一个服务器端 PHP 脚本,用于将来自 C++ 应用程序的数据存储在 MySQL 数据库中。我要存储在 MySQL 数据库中的数据是一个原始的 json 字符串(它是实验数据,稍后处理)。json 字符串由 C++ 应用程序形成。它大约有 70 kB 大(所以它很大!)并通过 POST 多部分请求发送到网络服务器。多部分请求是通过 libcurl 形成的:
foreach (const HttpKeyValuePair& kv, localServerCommand.httpKeyValuePairs) {
if (curl_formadd(&httpPostFirst, &httpPostLast, CURLFORM_PTRNAME, kv.key.c_str(),
CURLFORM_NAMELENGTH, (long) kv.key.size(),
CURLFORM_PTRCONTENTS, kv.value.c_str(),
CURLFORM_CONTENTSLENGTH, (long) kv.value.size(),
CURLFORM_CONTENTTYPE, "text/plain",
CURLFORM_END) != 0) {
cerr << "Error assembling form data" << endl;
}
}
[...]
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &receiveData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &receiveBuffer);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
if (useSimplePost) { // Only true if postString.size() < 200 byte
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString.c_str());
} else {
// Mutlipart
curl_easy_setopt(curl, CURLOPT_HTTPPOST, httpPostFirst);
}
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlErrorBuffer);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
CURLcode errorCode = curl_easy_perform(curl);
curl_easy_cleanup(curl);
(只是为了解决任何疑问:我检查了wireshark......他正在使用多部分帖子。使用简单帖子的分支仅存在,因为我认为可以通过省略多部分标题来节省网络连接更频繁,小要求。)
但是,现在有趣的部分是:我的服务器端脚本从不接收 json 字符串。应该携带 json 字符串的字段,称为“数据”,不是 PHP 中 $_POST 结构的一部分!更奇怪的是,所有其他字段都在那里。出于测试目的,我将服务器上的 PHP $_GET、$_POST 和 $_FILES 变量转储到一个日志文件中,对于相关请求,它们看起来像这样:
------
GET
------
array (
)
------
POST
------
array (
'id' => '130',
'nonceid' => '4656',
'authentication' => 'fjOynwtBDE/g/llkQlSgrGUx0ttfJMarExF6E3jg0/QeRgzvp+Chr0XqEIzoK6Rm4/19Q6KIA/Lx32Ti1Y+cQhVdF70AS8GaI2i+0FO3Uj7WfFl4FotUzpbyLpD5/AUe0KOiGA==',
)
------
FILES
------
array (
)
使用我的本地服务器时,“数据”字段是 $_POST 的一部分。'data' 字段是发送到服务器的第一个字段,这意味着它首先通过上面的 curl_formadd 循环写入,TCP 流中的第一个字段通过wireshark 检查,也是 $_POST 中的第一个字段我的本地服务器上的数组。
服务器测试
发现这个问题后,我测试了服务器并尝试使用 Firefox 通过 WordPress 上传文件,以测试服务器是否拒绝任何大的 $_POST 字段。然而,上传似乎工作(测试上传一个大的PNG,比我要上传的json数据大)。
下一个测试是使“数据”字段更小。我测试上传〜900字节的重复字符串
"shorter amount of data with special characters +/=?=?$§+#+\'*>< "
这也有效(使用多部分帖子)。
问题
我希望长的“数据”字段可以作为 $_POST 变量的一部分,就像它在我的开发机器上一样。我不知道是什么导致了这个问题。它可以是我正在使用的多部分 mime 类型(“text/plain”)吗?Apache/PHP 中是否有任何限制 POSTFIELD 大小的配置(我只知道整体 POST 大小限制)?
我怀疑这是一个奇特的服务器配置问题。但是,我对冗长且(如果您不花时间在上面)复杂的 httpd.conf 知之甚少。
有谁知道是什么导致了这个问题以及如何在我的本地服务器上重现它?甚至如何解决这个问题?
提前致谢!