Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sprintf raw bytes to string in C?

I am sending some raw bytes over the wire in C (using HTTP). I'm currently doing it like this:

// 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);

In JavaScript, I then read this data using code like this:

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();

which prints [42, 43] as it should.

I'm wondering if there is a more elegant way to do this on the server-side though, e.g.

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

Where %4b is a made-up format specifier which just says: copy the 4 bytes from that address into the string (which would be "*\0\0\0") Is there a format specifier like the fictional %4b that does something like this?

like image 473
michaelsnowden Avatar asked May 20 '26 11:05

michaelsnowden


1 Answers

It is an XY problem, you are asking about how to use sprintf() to solve your problem, rather than simply asking how to solve your problem. YOur actual problem is how to make that code more "elegant".

There is no particular reason to send the data in a single write operation - the network stack buffering will ensure that the data is packetised efficiently:

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) ) ; 

Note that X and Y will be written in the native machine byte order, which may be incorrect at the receiver. More generically then:

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) ) ; 
like image 85
Clifford Avatar answered May 23 '26 01:05

Clifford



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!