19g*_*g96 2 php c++ binary http
我正在为我用c ++编写的第一个程序创建一个更新机制.理论是:
大多数都有效,但收到的二进制文件格式不正确.当我将格式错误的exe与工作exe进行比较时,我\r\n在编译的exe中有s的区别.好像\r是加倍了.
我下载的c ++代码:
void checkForUpdates () {
SOCKET sock = createHttpSocket (); // creates the socket, nothing wrong here, other requests work
char* msg = (char*)"GET /u/2 HTTP/1.1\r\nHost: imgup.hu\r\nUser-Agent: imgup uploader app\r\nVersion: 1\r\n\r\n";
if (send(sock, msg, strlen(msg), 0) == SOCKET_ERROR) {
error("send failed with error\n");
}
shutdown(sock, SD_SEND);
FILE *fp = fopen("update.exe", "w");
char answ[1024] = {};
int iResult;
bool first = false;
do {
if ((iResult = recv(sock, answ, 1024, 0)) < 0) {
error("recv failed with error\n");
}
if (first) {
info (answ); // debug purposes
first = false;
} else {
fwrite(answ, 1, iResult, fp);
fflush(fp);
}
} while (iResult > 0);
shutdown(sock, SD_RECEIVE);
if (closesocket(sock) == SOCKET_ERROR) {
error("closesocket failed with error\n");
}
fclose(fp);
delete[] answ;
}
Run Code Online (Sandbox Code Playgroud)
和我的PHP来处理请求
<?php
if (!function_exists('getallheaders')) {
function getallheaders() {
$headers = '';
foreach ($_SERVER as $name => $value) {
if (substr($name, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
}
}
return $headers;
}
}
$version = '0';
foreach (getallheaders() as $name => $value) {
if (strtolower ($name) == 'version') {
$version = $value;
break;
}
}
if ($version == '0') {
exit('error');
}
if ($handle = opendir('.')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != '.' && $entry != '..' && $entry != 'u.php') {
if (intval ($entry) > intval($version)) {
header('Content-Version: ' . $entry);
header('Content-Length: ' . filesize($entry));
header('Content-Type: application/octet-stream');
echo "\r\n";
ob_clean();
flush();
readfile($entry);
exit();
}
}
}
closedir($handle);
}
echo 'error2';
?>
Run Code Online (Sandbox Code Playgroud)
注意我发送标题后刷新内容的方式,ob_clean(); flush();所以我不必用c ++解析它们.写入文件的第一个字节很好,所以我怀疑这里有什么问题.
另外,二进制文件的示例比较http://i.imgup.hu/meC16C.png
问题:http是否\r\n在二进制文件传输中转义?如果不是,导致此行为的原因是什么?如何解决此问题?
fopen 以您指定的模式打开文件,首先读/写/两者,然后追加,然后是二进制标识符.
r/w应该对你清楚,追加也很明显.你的案例中的诡计和麻烦是二元模式.
如果文件被作为文本文件(没有"b")进行威胁,则根据应用程序运行的环境,在文本模式下的输入/输出操作中可能会发生一些特殊字符转换,以使它们适应特定于系统的文本文件格式.在Windows上,这将是\ r \n,在Linux机器上你有\n并且在某些架构上存在,它是\ r \n.
在您的情况下,输入文件将作为文本文件读取.这意味着,从HTTP数据中读取文件时,所有行结尾都会被转换.
将文件作为二进制文件打开(实际上是!)避免了文件不再具有二进制文件的麻烦.
问题是输出文件没有以二进制模式打开.要做到这一点,将模式更改为"wb"而不是"w",如下所示:
FILE *fp = fopen("update.exe", "wb");
Run Code Online (Sandbox Code Playgroud)
在Windows上的文本模式下,ctrl + z字符指定搜索/读取时文件的结尾,并且在写入时将换行符\n转换为\ r \n,并且在读取时将\ r \n对转换为\n.在二进制模式下,不以任何方式解释或翻译文件数据.
在其他平台上,翻译可能不适用,但通过指定显式模式来显示代码的意图仍然是一种好的做法,即使在非必要时也是如此.对于可移植的代码尤其如此.
| 归档时间: |
|
| 查看次数: |
1304 次 |
| 最近记录: |