|
Home > Archive > Unix Programming > February 2004 > Bits how to program them
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Bits how to program them
|
|
| Marcia Hon 2004-02-10, 12:34 pm |
| Hi,
I am writing a P2P client application. As such, I am creating packets that
are to be sent between the peers. I would like to know how in C these bits
of the packets may be programmed. These bits need to be continguous.
For example: I create a packet of size 5. 2 bytes for the size, 1 for the
message type, 1 for the start flag, 1 for the body, and 1 for the end flag.
How to I program this?
I have tried the following:
unsigned size:16;
unsigned type:8;
unsigned start:8;
unsigned body:8;
unsigned end:8;
How to I keep them contiguous? I would like to eventually send them over the
socket connection. And therefore would like to store them in an unsigned *
buffer.
Please, please help.
Thank you,
Marcia
| |
| Jem Berkes 2004-02-10, 12:34 pm |
| > I am writing a P2P client application. As such, I am creating packets
> that are to be sent between the peers. I would like to know how in C
> these bits of the packets may be programmed. These bits need to be
> continguous.
Probably easiest to work with an unsigned char array. The byte is the
fundamental unit for data access. If you want to work on bits within a
byte, you can do so with bitwise operators.
> For example: I create a packet of size 5. 2 bytes for the size, 1 for
> the message type, 1 for the start flag, 1 for the body, and 1 for the
> end flag.
Maybe this helps... I'm assuming everything in your above list is bytes.
#define HEADER_SIZE 5
#define SIZE0_OFFSET 0 /* size low byte */
#define SIZE1_OFFSET 1 /* size byte byte */
#define TYPE_OFFSET 2
unsigned char header[HEADER_SIZE]; /* contiguous bytes in here */
Now you can manipulate the individual fields like this:
unsigned char message_type = header[TYPE_OFFSET];
unsigned int length = header[SIZE0_OFFSET] + (header[SIZE1_OFFSET] << 8);
The << 8 performs bit shift to form one large integer out of the two
bytes.
> How to I keep them contiguous? I would like to eventually send them
> over the socket connection. And therefore would like to store them in
> an unsigned * buffer.
If you access the contents like this, then you can simply send your
header buffer in one go, all bytes are in there.
--
Jem Berkes
http://www.sysdesign.ca/
| |
| Nick Landsberg 2004-02-10, 1:34 pm |
|
Jem Berkes wrote:
>=20
>=20
> Probably easiest to work with an unsigned char array. The byte is the=20
> fundamental unit for data access. If you want to work on bits within a =
> byte, you can do so with bitwise operators.
>=20
>=20
This is 6 bytes. Maybe this is part of the problem?
[color=blue]
>=20
>=20
> Maybe this helps... I'm assuming everything in your above list is bytes=
=2E
>=20
> #define HEADER_SIZE 5
> #define SIZE0_OFFSET 0 /* size low byte */
> #define SIZE1_OFFSET 1 /* size byte byte */
> #define TYPE_OFFSET 2
>=20
> unsigned char header[HEADER_SIZE]; /* contiguous bytes in here */
>=20
> Now you can manipulate the individual fields like this:
> unsigned char message_type =3D header[TYPE_OFFSET];
> unsigned int length =3D header[SIZE0_OFFSET] + (header[SIZE1_OFFSET] <<=
8);
>=20
This presupposes a particular endian-ness. May not be valid.
> The << 8 performs bit shift to form one large integer out of the two=20
> bytes.
>=20
>=20
>=20
>=20
> If you access the contents like this, then you can simply send your=20
> header buffer in one go, all bytes are in there.
>=20
The OP could also try Unions.
--=20
=D1
"It is impossible to make anything foolproof because fools are so=20
ingenious" - A. Bloch
| |
| Jem Berkes 2004-02-10, 2:35 pm |
| >> #define HEADER_SIZE 5
> 8);
> This presupposes a particular endian-ness. May not be valid.
Since the OP is defining their own packet format (hence, knows the byte
order) the code is quite portable. This is a better method than trying to
memcpy bytes into an int space, or other goofy tricks like that.
--
Jem Berkes
http://www.sysdesign.ca/
| |
| Nils O. newsgroup user 2004-02-10, 6:34 pm |
| > Hi,
>
> I am writing a P2P client application. As such, I am creating packets that
> are to be sent between the peers. I would like to know how in C these bits
> of the packets may be programmed. These bits need to be continguous.
>
> For example: I create a packet of size 5. 2 bytes for the size, 1 for the
> message type, 1 for the start flag, 1 for the body, and 1 for the end flag.
>
> How to I program this?
>
> I have tried the following:
Which is atleast 6 bytes..
>
> unsigned size:16;
> unsigned type:8;
> unsigned start:8;
> unsigned body:8;
> unsigned end:8;
>
> How to I keep them contiguous? I would like to eventually send them over the
> socket connection. And therefore would like to store them in an unsigned *
> buffer.
struct whatever {
unsigned size:16;
unsigned type:8;
unsigned start:8;
unsigned body:8;
unsigned end:8;
} __attribute__((__packed__));
That's a gcc extension though.
--
Vennlig hilsen/Best Regards
Nils Olav Selåsdal
System Engineer
w w w . u t e l s y s t e m s . c o m
| |
| Jerry Feldman 2004-02-15, 12:33 am |
| On Wed, 11 Feb 2004 07:34:29 GMT
noselasd@frisurf.no (Nils O. Sel=E5sdal) wrote:
>=20
> struct whatever {
> unsigned size:16;
> unsigned type:8;
> unsigned start:8;
> unsigned body:8;
> unsigned end:8;
> } __attribute__((__packed__));
>=20
> That's a gcc extension though.
Most compilers support packing, some by using #pragma, but it is usually
implementation defined.=20
Sending binary data over a socket connection is not problematic per se.,
but portability could be an issue, especially between systems that are
different endian models.=20
--=20
Jerry Feldman <gaf-nospam-at-blu.org>
Boston Linux and Unix user group
http://www.blu.org PGP key id:C5061EA9
PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
| |
| Pascal Bourguignon 2004-02-15, 1:34 am |
| "Marcia Hon" <honm@rogers.com> writes:
> Hi,
>
> I am writing a P2P client application. As such, I am creating packets that
> are to be sent between the peers. I would like to know how in C these bits
> of the packets may be programmed. These bits need to be continguous.
You don't need to send bits, you could send ASCII text as well.
fprintf(socket,"(%u %u %u %u %u)\n",size,type,start,body,end);
and a the other end:
fscanf(socket,"(%u %u %u %u %u)\n",&size,&type,&start,&body,&end);
> For example: I create a packet of size 5. 2 bytes for the size, 1 for the
> message type, 1 for the start flag, 1 for the body, and 1 for the end flag.
>
> How to I program this?
>
> I have tried the following:
>
> unsigned size:16;
> unsigned type:8;
> unsigned start:8;
> unsigned body:8;
> unsigned end:8;
>
> How to I keep them contiguous? I would like to eventually send them over the
> socket connection. And therefore would like to store them in an unsigned *
> buffer.
Write it EXACTLY as you say it!
unsigned char buffer[1024];
put_bits(buffer,0,16,size);
put_bits(buffer,24,8,type);
put_bits(buffer,32,8,start);
put_bits(buffer,40,8,body);
put_bits(buffer,48,8,send);
send_bits(buffer,54);
--
__Pascal_Bourguignon__ http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
| |
| Jem Berkes 2004-02-15, 6:34 am |
| >> That's a gcc extension though.
> Most compilers support packing, some by using #pragma, but it is usually
> implementation defined.
>
> Sending binary data over a socket connection is not problematic per se.,
> but portability could be an issue, especially between systems that are
> different endian models.
But endian-ness shouldn't be an issue if you're sending character arrays
and explicitly reconstructing integers based on your definition of high
byte, low byte.
--
Jem Berkes
http://www.sysdesign.ca/
|
|
|
|
|