Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Markus Wichmann <nullplan@gmx.net> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: What is the right way to do this simple thing |
| Date | 2012-03-11 13:47 +0100 |
| Organization | 1&1 Internet AG |
| Message-ID | <ogju29-op8.ln1@voyager.wichi.de.vu> (permalink) |
| References | <4f5ba2ed.1944110152@text.giganews.com> |
On 10.03.2012 20:26, Richard Harter wrote:
> Suppose that I have some data that is pointer free. It isn't
> necessarily serialized in some format such as JSON but I would like to
> be able to copy it from one from one machine to another compatible
> machine and use it without trouble. Also I don't want to pass around
> a collection of items and I want everything to be properly aligned.
>
> [...]
JSON makes an object into a string representation that can be passed
around and parsed. Note, however, that parsing is expensive; more so,
the more complicated a language gets.
One simple way to send a structure over the network would be to define a
packet format _to_the_byte_ and then use that. For instance, if you have
to pass the structure:
struct foo {
unsigned int foo;
unsigned int bar;
char* string;
}
You could define a packet structure:
- All data is sent in big endian (as is custom in the network)
Offset | Size | Description
0 4 foo
4 4 bar
8 4 len
12 len string
Neither len nor string include a terminating NULL character.
Then you would send the stuff:
#include <limits.h>
#if CHAR_BIT > 8
#error Sorry, this code only works on platforms with 8 bit bytes.
#endif
static void uint_to_buf_be(unsigned char* start, unsigned int data)
{
start[0] = (data >> 24) & 255;
start[1] = (data >> 16) & 255;
start[2] = (data >> 8) & 255;
start[3] = (data >> 0) & 255;
}
void send_struct_foo(struct foo* data)
{
static char buf[1500];
size_t len;
len = strlen(data->string);
uint_to_buf_be(buf + 0, data->foo);
uint_to_buf_be(buf + 4, data->bar);
uint_to_buf_be(buf + 8, len);
memcpy(buf + 12, data->string, len);
send(out_socket, buf, len + 12);
}
And receive it:
#include <limits.h>
#if CHAR_BIT > 8
#error Sorry, this code only works on platforms with 8 bit bytes.
#endif
static unsigned int buf_be_to_uint(unsigned char* start)
{
unsigned int r;
r = start[0] * 16777216
+ start[1] * 65536
+ start[2] * 256
+ start[3];
return r;
}
void recv_struct_foo(struct foo* data)
{
static unsigned char buf[1500];
size_t len;
recv(in_socket, buf, sizeof buf);
data->foo = buf_be_to_uint(buf + 0);
data->bar = buf_be_to_uint(buf + 4);
len = buf_be_to_uint(buf + 8);
data->string = malloc(len+1);
if (!data->string) abort();
memcpy(data->string, buf + 12, len);
data->string[len] = 0;
}
Another, oft employed and "more efficient" solution is simply using
memcpy(). However, that will only work when sending the data to a
machine with the same ABI. That is, same endianess, same rules for
alignment in aggregates, same rules for alignment _of_ aggregates; when
sending them, same representation of floating-point numbers and so on.
There are very many ways that can go wrong. You experienced some of them
on your own.
HTH,
Markus
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-10 19:26 +0000
Re: What is the right way to do this simple thing Don Y <this@isnotme.com> - 2012-03-10 12:57 -0700
Re: What is the right way to do this simple thing ImpalerCore <jadill33@gmail.com> - 2012-03-10 14:12 -0800
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-10 23:31 +0000
Re: What is the right way to do this simple thing Ian Collins <ian-news@hotmail.com> - 2012-03-11 13:06 +1300
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 00:44 +0000
Re: What is the right way to do this simple thing Ian Collins <ian-news@hotmail.com> - 2012-03-11 14:15 +1300
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 04:46 +0000
Re: What is the right way to do this simple thing Ian Collins <ian-news@hotmail.com> - 2012-03-11 21:27 +1300
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 17:23 +0000
Re: What is the right way to do this simple thing Ian Collins <ian-news@hotmail.com> - 2012-03-12 10:01 +1300
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 21:18 +0000
Re: What is the right way to do this simple thing Ian Collins <ian-news@hotmail.com> - 2012-03-14 10:23 +1300
Re: What is the right way to do this simple thing Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-03-11 11:59 +0000
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 16:51 +0000
Re: What is the right way to do this simple thing Gene <gene.ressler@gmail.com> - 2012-03-13 07:32 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 21:46 +0000
Re: What is the right way to do this simple thing ImpalerCore <jadill33@gmail.com> - 2012-03-12 07:28 -0700
Re: What is the right way to do this simple thing ImpalerCore <jadill33@gmail.com> - 2012-03-12 08:13 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 21:51 +0000
Re: What is the right way to do this simple thing Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-10 14:21 -0800
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 01:40 +0000
Re: What is the right way to do this simple thing Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-11 14:11 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 21:56 +0000
Re: What is the right way to do this simple thing Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-14 14:55 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-15 21:55 +0000
Re: What is the right way to do this simple thing Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-19 13:33 -0700
Re: What is the right way to do this simple thing Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-03-10 15:21 -0800
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 00:47 +0000
Re: What is the right way to do this simple thing Philip Lantz <prl@canterey.us> - 2012-03-11 01:07 -0800
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 16:14 +0000
Re: What is the right way to do this simple thing Markus Wichmann <nullplan@gmx.net> - 2012-03-11 13:47 +0100
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 16:24 +0000
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 21:01 +0000
Re: What is the right way to do this simple thing Anders Wegge Keller <wegge@wegge.dk> - 2012-03-12 00:05 +0100
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 21:57 +0000
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-11 23:06 +0000
Re: What is the right way to do this simple thing Geoff <geoff@invalid.invalid> - 2012-03-11 17:34 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-13 22:00 +0000
Re: What is the right way to do this simple thing Geoff <geoff@invalid.invalid> - 2012-03-13 18:12 -0700
Re: What is the right way to do this simple thing cri@tiac.net (Richard Harter) - 2012-03-14 03:38 +0000
Re: What is the right way to do this simple thing Geoff <geoff@invalid.invalid> - 2012-03-14 00:49 -0700
csiph-web