[英]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.