- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在创建一个 HTTP 客户端,它根据命令行参数下载网页。它接受参数,查找域名以获取 IP 地址,创建套接字,连接到服务器并发送 GET 请求并等待回复。这一切都很好,但是当我使用缓冲区和 while 循环阅读我的回复时,我也收到了一些不可读的字符。如果您运行代码并查看 html,您将在页面上到处看到不可读的字符。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int socket_desc, i, bytes_read;
char server_reply[1024], ip[100], request[100];;
char *hostname = argv[1];
struct sockaddr_in server;
struct hostent *he;
struct in_addr **addr_list;
FILE *fp;
if ((he = gethostbyname(hostname)) == NULL) {
//gethostbyname failed
herror("gethostbyname\n");
return 1;
}
addr_list = (struct in_addr **) he->h_addr_list;
for(i = 0; addr_list[i] != NULL; i++) {
//Return the first one;
strcpy(ip , inet_ntoa(*addr_list[i]) );
}
//Create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
printf("Could not create socket!\n");
}
server.sin_addr.s_addr = inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons(80);
//Connect to remote server
if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
printf("connect error!\n");
return 1;
}
printf("Connected...\n");
//Send some data
snprintf(request, 99, "GET / HTTP/1.1\r\n"
"Host: %s\r\n"
"\r\n\r\n", hostname
);
if (send(socket_desc, request, strlen(request), 0) < 0) {
puts("Send failed!\n");
return 1;
}
puts("Data Sent...\n");
//Receive a reply from the server
fp = fopen("/home/localusr/Desktop/ouput.html", "w+");
while (bytes_read = read(socket_desc, server_reply, sizeof(server_reply)) > 0) {
fputs(server_reply, fp);
memset(server_reply, 0, sizeof(server_reply));
}
do {
bytes_read = read(socket_desc, server_reply, sizeof(server_reply));
fputs(server_reply, fp);
memset(server_reply, 0, sizeof(server_reply));
} while (bytes_read > 0);
printf("reply received...\n");
fclose(fp);
close(socket_desc);
return 0;
}
对于缩进不佳的代码感到抱歉。非常感谢任何帮助。我正在使用 Ubuntu 机器并使用 gcc 编译我的代码。
编辑:
orb.ws.require.lib--> <script type="text/javascript">/*
be2
be2 不应该存在。 * 也得到 '@' 符号
最佳答案
编辑: 将我的评论放在这里:
请注意,例如www.bbc.co.uk 响应 header 显示“Transfer-Encoding: chunked”,这意味着每个 block 都有一个十六进制数字表示长度,后跟数据,然后是\r\n。
也就是说,根据您的示例:
be2\r\n => 0xbe2\r\n => 3042\r\n
或“Here follows 3042 bytes”(在\r\n 之后又名 CRLF 或十六进制 0d0a
)。
Example大块:
e\r\nStack Exchange
| | ||||||||||||||
| | +............+
| | |
| | +-------- 14 bytes
| +----------------- \r\n
+-------------------- 0x0e == 14 dec in hex
旧:
代替 memset
等,您可以通过以下方式正确终止读取字节:
while ( (bytes_read = read(socket_desc, server_reply, sizeof(server_reply) - 1)) > 0) {
server_reply[bytes_read] = 0x00;
在此之后,bytes_read
之外的任何内容都将被fputs
。
当您memset
整个缓冲区为0
但也 读入整个缓冲区时 - memset 无效除非读取小于缓冲区大小。您只需在完整 (1024) 次读取和写入 1024 + 垃圾时覆盖所有零,直到第一个零。
read()
返回读取的字节数。通过将 server_reply[bytes_read]
设置为 0
,您实际上终止了实际数据。把它变成一个 C 字符串。如果不将最后一个字节设置为零,fputs()
将在 bytes_read
之后继续输出垃圾,直到第一个零或崩溃。
换句话说; read()
最多读取 size
字节,不关心是否全为零字节。如果您告诉 read()
读取 356GiB 的数据,并且文件描述符提供 356GiB 的零(如 0x00 字节,而不是 ASCII 0)——这就是您得到的结果。
您的套接字不会以零终止传送。它像您的服务器一样将零字节作为数据的一部分传送。假设您以零字节传输图像或其他一些数据;换句话说:它不是 read()
获取的零终止字符串。
还要注意 sizeof
之后的 - 1
– 为空字节腾出空间。
fputs 然而 写入直到第一个终止空字节,但不将其包含在输出中(如果您正在写入缓冲的 string<,这通常是您想要的/strong>数据)。
char buf[8];
Char 未初始化且包含垃圾。例如它可以是:
buf[0] == 0x13
buf[1] == 0x0a
buf[2] == 0x00
buf[3] == 0x65
buf[4] == 0x78
buf[5] == 0xf3
buf[6] == 0x00
buf[7] == 0xaf
例如,除了 buf 你还有随机垃圾
buf[7+1] == 0xde
buf[7+2] == 0xa0
buf[7+3] == 0x33
buf[7+3] == 0x00
bytes_read = read(soc, buf, 8); soc delivers: 'ABCDEFG'
缓冲区现在是:
buf[0] == 0x41 (A)
buf[1] == 0x42 (B)
buf[2] == 0x43 (C)
buf[3] == 0x44 (D)
buf[4] == 0x45 (E)
buf[5] == 0x46 (F)
buf[6] == 0x47 (G)
buf[7] == 0xaf (H)
但是 buf[7]
之后的字节仍然是垃圾;并且您的 fputs()
将读取数据并将其传递到文件,直到第一个为零。
这就是为什么你会说:
bytes_read = read(soc, buf, 7);
buf[bytes_read] = 0x00;
现在我们只读A-G。最后一个字节设置为 0。
这里 fputs(buf, fh)
正在写直到第一个 \0
,换句话说 ABCDEFG
。
如果服务器现在在下一次运行时只传送,比方说,只有两个字节:
buf[0] == 0x48 (H)
buf[1] == 0x5A (Z)
然后 bytes_read
将为 2 并且声明:
buf[bytes_read] = 0x00 ===> buf[2] = 0x00
这给了你
buf[0] == 0x48 (H)
buf[1] == 0x5A (Z)
buf[2] == 0x00 (0x00) <<--- nulled out
+---.
buf[3] == 0x44 (D) | \
buf[4] == 0x45 (E) | \
buf[5] == 0x46 (F) | }--->>> garbage from previous read.
buf[6] == 0x47 (G) | /
buf[7] == 0x00 (0x00) | /
+---/
这里 fputs(buf, fh)
正在写到第一个 \0
,换句话说 HZ
。
关于在 C 中创建 HTTP 客户端以下载网页以供离线查看,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27421600/
我将 Bootstrap 与 css 和 java 脚本结合使用。在不影响前端代码的情况下,我真的很难在css中绘制这个背景。在许多问题中,人们将宽度和高度设置为 0%。但是由于我的导航栏,我不能使用
我正在用 c 编写一个程序来读取文件的内容。代码如下: #include void main() { char line[90]; while(scanf("%79[^\
我想使用 javascript 获取矩阵数组的所有对 Angular 线。假设输入输出如下: input = [ [1,2,3], [4,5,6], [7,8,9], ] output =
可以用pdfmake绘制lines,circles和other shapes吗?如果是,是否有documentation或样本?我想用jsPDF替换pdfmake。 最佳答案 是的,有可能。 pdfm
我有一个小svg小部件,其目的是显示角度列表(参见图片)。 现在,角度是线元素,仅具有笔触,没有填充。但是现在我想使用一种“内部填充”颜色和一种“笔触/边框”颜色。我猜想line元素不能解决这个问题,
我正在为带有三角对象的 3D 场景编写一个非常基本的光线转换器,一切都工作正常,直到我决定尝试从场景原点 (0/0/0) 以外的点转换光线。 但是,当我将光线原点更改为 (0/1/0) 时,相交测试突
这个问题已经有答案了: Why do people write "#!/usr/bin/env python" on the first line of a Python script? (22 个回
如何使用大约 50 个星号 * 并使用 for 循环绘制一条水平线?当我尝试这样做时,结果是垂直(而不是水平)列出 50 个星号。 public void drawAstline() { f
这是一个让球以对角线方式下降的 UI,但球保持静止;线程似乎无法正常工作。你能告诉我如何让球移动吗? 请下载一个球并更改目录,以便程序可以找到您的球的分配位置。没有必要下载足球场,但如果您愿意,也可以
我在我的一个项目中使用 Jmeter 和 Ant,当我们生成报告时,它会在报告中显示 URL、#Samples、失败、成功率、平均时间、最短时间、最长时间。 我也想在报告中包含 90% 的时间线。 现
我有一个不寻常的问题,希望有人能帮助我。我想用 Canvas (android) 画一条 Swing 或波浪线,但我不知道该怎么做。它将成为蝌蚪的尾部,所以理想情况下我希望它的形状更像三角形,一端更大
这个问题已经有答案了: Checking Collision of Shapes with JavaFX (1 个回答) 已关闭 8 年前。 我正在使用 JavaFx 8 库。 我的任务很简单:我想检
如何按编号的百分比拆分文件。行数? 假设我想将我的文件分成 3 个部分(60%/20%/20% 部分),我可以手动执行此操作,-_-: $ wc -l brown.txt 57339 brown.tx
我正在努力实现这样的目标: 但这就是我设法做到的。 你能帮我实现预期的结果吗? 更新: 如果我删除 bootstrap.css 依赖项,问题就会消失。我怎样才能让它与 Bootstrap 一起工作?
我目前正在构建一个网站,但遇到了 transform: scale 的问题。我有一个按钮,当用户将鼠标悬停在它上面时,会发生两件事: 背景以对 Angular 线“扫过” 按钮标签颜色改变 按钮稍微变
我需要使用直线和仿射变换绘制大量数据点的图形(缩放图形以适合 View )。 目前,我正在使用 NSBezierPath,但我认为它效率很低(因为点在绘制之前被复制到贝塞尔路径)。通过将我的数据切割成
我正在使用基于 SVM 分类的 HOG 特征检测器。我可以成功提取车牌,但提取的车牌除了车牌号外还有一些不必要的像素/线。我的图像处理流程如下: 在灰度图像上应用 HOG 检测器 裁剪检测到的区域 调
我有以下图片: 我想填充它的轮廓(即我想在这张图片中填充线条)。 我尝试了形态学闭合,但使用大小为 3x3 的矩形内核和 10 迭代并没有填满整个边界。我还尝试了一个 21x21 内核和 1 迭代,但
我必须找到一种算法,可以找到两组数组之间的交集总数,而其中一个数组已排序。 举个例子,我们有这两个数组,我们向相应的数字画直线。 这两个数组为我们提供了总共 7 个交集。 有什么样的算法可以帮助我解决
简单地说 - 我想使用透视投影从近裁剪平面绘制一条射线/线到远裁剪平面。我有我认为是使用各种 OpenGL/图形编程指南中描述的方法通过单击鼠标生成的正确标准化的世界坐标。 我遇到的问题是我的光线似乎
我是一名优秀的程序员,十分优秀!