簡體   English   中英

sprintf 原始字節到 C 中的字符串?

[英]sprintf raw bytes to string in C?

我在 C 中通過網絡發送一些原始字節(使用 HTTP)。 我目前正在這樣做:

// response is a large buffer
int n = 0; // response length
int x = 42; // want client to read x
int y = 43; // and y 

// write a simple HTTP response containing a 200 status code then x and y in binary format
strcpy(response, "HTTP/1.1 200\r\n\r\n");
n += 16; // status line we just wrote is 16 bytes long
memcpy(response + n, &x, sizeof(x));
n += sizeof(x);
memcpy(response + n, &y, sizeof(y));
n += sizeof(y);
write(client, response, n);

在 JavaScript 中,我然后使用如下代碼讀取這些數據:

request = new XMLHttpRequest();
request.responseType = "arraybuffer";
request.open("GET", "/test");
request.onreadystatechange = function() { if (this.readyState === XMLHttpRequest.DONE) { console.log(new Int32Array(this.response)) } }
request.send();

它應該打印[42, 43]

我想知道在服務器端是否有更優雅的方法來做到這一點,例如

n += sprintf(response, "HTTP/1.1 200\r\n\r\n%4b%4b", &x, &y);

其中%4b是一個虛構的格式說明符,它只是說:將該地址中的 4 個字節復制到字符串中(即“*\\0\\0\\0”)是否有像虛構的%4b這樣的格式說明符像這樣的東西?

這是一個 XY 問題,您是在詢問如何使用sprintf()來解決您的問題,而不是簡單地詢問如何解決您的問題。 您的實際問題是如何使該代碼更“優雅”。

沒有特別的理由在單個寫操作中發送數據 - 網絡堆棧緩沖將確保數據有效地打包:

static const char header[] = "HTTP/1.1 200\r\n\r\n" ;
write( client, header, sizeof(header) - 1 ) ;
write( client, &x, sizeof(x) ) ;
write( client, &y, sizeof(y) ) ; 

請注意,X 和 Y 將以本機機器字節順序寫入,這在接收方可能不正確。 更一般地說:

static const char header[] = "HTTP/1.1 200\r\n\r\n" ;
write( client, header, sizeof(header) - 1 ) ;

uint32_t nl = htonl( x ) ;
write( client, &nl, sizeof(nl) ) ;

nl = htonl( y ) ;
write( client, &nl, sizeof(nl) ) ; 

是否有像虛構的 %4b 這樣的格式說明符?

不,沒有,你的方法很好。 我建議使用snprintf和一些檢查來避免緩沖區溢出,添加 ex。 static_assert(sizeof(int) == 4, "")檢查平台是否使用大端和類似環境以及錯誤處理並避免未定義的行為檢查。

也就是說,您可以多次使用%c printf 說明符,例如"%c%c%c%c", ((char*)&x)[3], ((char*)&x)[2], ((char*)&x)[1], ((char*)&x)[0]打印 4 個字節。 您可以將其包裝在宏中並執行以下操作:

#include <stdio.h>

#define PRI_BYTES_4  "%c%c%c%c"
#define ARG_BYTES_BE_4(var) \
    ((const char*)&(var))[3], \
    ((const char*)&(var))[2], \
    ((const char*)&(var))[1], \
    ((const char*)&(var))[0]

int main() {
    int var = 
        'l' << 24 |
        'a' << 16 | 
        'm' << 8 |
        'e';
    printf("Hello, I am " PRI_BYTES_4 ".\n",
        ARG_BYTES_BE_4(var));
    // will print `Hello, I am lame.`
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM