[英]Byte ordering HTTP Client
我写了一个简单的HTTP客户端,可以从主机请求数据。
我正在使用getaddrinfo(3)。 使用“GET / HTTP / 1.1”请求,我可以下载给定http主机的HTML页面。
这是我的代码的一部分:
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; // Internet Protocol (IP) socket
hints.ai_socktype = SOCK_STREAM; // TCP
int res = getaddrinfo("example.com", "http", &hints, &ai);
if (res != 0)
ERROR_EXIT("getaddrinfo: %s\n", gai_strerror(res));
int sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd < 0)
ERROR_EXIT("socket: %s\n", strerror(errno));
if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)
ERROR_EXIT("connect: %s\n", strerror(errno));
FILE *sockfile = fdopen(sockfd, "r+");
if (sockfile == NULL)
ERROR_EXIT("fdopen: %s\n", strerror(errno));
// send a GET request to the server:
if (fputs("GET / HTTP/1.1\r\n\r\n", sockfile) == EOF)
ERROR_EXIT("fputs: %s\n", strerror(errno));
if (fflush(sockfile) == EOF)
ERROR_EXIT("fflush: %s\n", strerror(errno));
char buf[1024];
// print the reply:
while (fgets(buf, sizeof(buf), sockfile) != NULL)
fputs(buf, stdout);
fclose(sockfile);
return 0;
下载HTML页面工作正常,但下载PNG图像例如"GET /image.png HTTP/1.1\\r\\n\\r\\n"
提供如下内容:
???????ݹh??DHDZ?yW]%?9a??J?6F?Ѧ?E???ݐTd?US?:)??I??M,?-????=??U??&???Nr? ???б???
b??]??8?6+?;??i䂢d?G?WA?rԺ?H[??]?Z5????g?{8??i\?qAC?@c??v.?rb??'<?T?????O?z?
q,yĜ?ŷZI???X??fM?l?Z??l:;M???ۦ?????c?\\?W6+???o?}_???紈A??GvG?p??6{??{%?????0?{?
%??ژ??l?$r<?????ft*'W?N?m߂Ҿ4??E?:^?#?&?%%
????Dw??Z?$??1?4?l%&2?f-5!?? ?E? 8...
我知道这是一个字节传输,我必须做字节排序,但不知道从哪里开始。
我知道我需要对PNG图像使用ntohl(3)和Big-endian顺序。 有人可以告诉我要查找什么以及如何处理这个问题?
我是否将此输出保存到.png文件,然后执行字节顺序或在创建.png文件之前执行此操作?
在决定它们应该处于哪个顺序之前写出图像的字节是没有多大意义的。你的下一行是什么, fopen()
?
如果你正在做一些像这样依赖于体系结构的东西,最好用#if
/ #elif
来保护特定于案例的部分,并使用#else
发出带有诊断消息的#error
。 如果一切都应该仍然有效,它可以只是#warning
......但是请将警告输入。稍后,当它停止工作时。
您可以测试的配置宏应该包括#ifdef __BIG_ENDIAN__
和#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
; 你可以通过-E -dD
'编译'来看看还有什么可用。 [会有很多; grep是你的朋友]
哦,“big endian”意味着如果你按地址顺序读取字节(a [0],a [1],a [2],...),那么这一端的字节是最重要/最高的'数字'。 因此“大端”。
编辑:这也可能引起关注......
FILE *sockfile = fdopen(sockfd, "r+"); // "r+"
if (sockfile == NULL)
ERROR_EXIT("fdopen: %s\n", strerror(errno));
if (fputs("GET / HTTP/1.1\r\n\r\n", sockfile) == EOF) // fputs...
问题比“字节顺序”更复杂。
好消息是字节顺序可能无关紧要 。 您现在获得的代码应该可以很好地发送和接收服务器的文本字符串。
坏消息是,如果要从服务器读取二进制数据,则需要以不同方式连接。 几点考虑:
听起来你可能不需要担心“POST”,“PUT”......或者除了“GET”之外的其他任何事情。
听起来你也不必担心“MIME类型”或“uuencoding / decoding” - 你只是按原样阅读数据。
您一定要从服务器的HTTP响应中读取Content-Type
和Content-Length
标头。
也许最简单的方法是在循环中调用fgetc()
,如果你正在读取二进制数据。 对字符串使用fgets()
,对Content-Length
字节使用fgetc()
来读取图像。
您可能希望使用fopen()
将图像字节写入文件。
但是调用fgets()消除了担心“字节顺序”的需要。
'希望有帮助......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.