C++ Sockets (in Linux) send data at bit level

Red Squirrel

No Lifer
May 24, 2003
70,157
13,567
126
www.anyf.ca
Normally when sending data through sockets its done at the byte level, you enter a string of say 10 characters, and set size to 10, and 10 bytes are sent (not counting other layer headers and such). But what if I only want to send 3 bits, followed by a string of 5 bytes, lets say. How would I go about doing this?

The current way I know of to send data is using Send() but I'm guessing there's perhaps another way. A good example of this is if a certain packet needs to have fields that look like this:

header: 1 byte
flag1: 1 bit
flag2: 1 bit
size:2 bytes
dynamic string: string of varying size
flag 3: 1 bit
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
A packet will always contain just bytes AFAIK.

Since you decide the data format of the bytes you're sending, it's up to you to put something in your data format to say that one of the bytes is only partially used.

e.g. have an int32 bit-count at the start of your packet, for packets up to .5 gigabits, or an int16 bit count for packets up to 64K bits.

For writing bits by bits:
The way I've done this for writing Flash files (which use packed bits) is to have writebits and readbits functions that serialize bits into a byte buffer of a class object.

The class object initializes bytes used to 0, adds bits to the current byte until filled, then starts a new byte and increments byte count.

The code was all for work so I can't share any of it though.

Edit: a much easier approach is just to pack flag bits together in bytes and waste a few bits, e.g.
#define FLAG_1 0x001
#define FLAG_2 0x002
#define FLAG_3 0x004 // 08, 10,20,40

// set method 1
byte b = ( FLAG_1 | FLAG_2 ) ;

// set method 2
byte c = 0 ;
if (flag_bool_1) { c += FLAG_1 ; }
if (flag_bool_2) { c += FLAG_2 ; }
 

dighn

Lifer
Aug 12, 2001
22,820
4
81
I've never heard of anything like this. heck the smallest data type you get to use is a byte in most compilers. Why send only 3 bits anyway? If it's a throughput issue I suppose you could package the bits into bytes and send them that way.
 

Red Squirrel

No Lifer
May 24, 2003
70,157
13,567
126
www.anyf.ca
hmm k so I could just do that then. Figured that I may run into protocols that would use partial bytes. I'm attempting to write a userfriendly sockets class that I can easily declare and use to send/receive data, so I'm writing functions like SendString and such and the class does all the connection handling rather then copy and paste blocks of code each time I want to write a socket program.
 

engineereeyore

Platinum Member
Jul 23, 2005
2,070
0
0
Packet headers measure data being sent in bytes, not bits, so I think you'd be safe ignoring the possibility of getting only bits.
 

smack Down

Diamond Member
Sep 10, 2005
4,507
0
0
Originally posted by: DaveSimmons
A packet will always contain just bytes AFAIK.

Since you decide the data format of the bytes you're sending, it's up to you to put something in your data format to say that one of the bytes is only partially used.

e.g. have an int32 bit-count at the start of your packet, for packets up to .5 gigabits, or an int16 bit count for packets up to 64K bits.

For writing bits by bits:
The way I've done this for writing Flash files (which use packed bits) is to have writebits and readbits functions that serialize bits into a byte buffer of a class object.

The class object initializes bytes used to 0, adds bits to the current byte until filled, then starts a new byte and increments byte count.

The code was all for work so I can't share any of it though.

Edit: a much easier approach is just to pack flag bits together in bytes and waste a few bits, e.g.
#define FLAG_1 0x001
#define FLAG_2 0x002
#define FLAG_3 0x004 // 08, 10,20,40

// set method 1
byte b = ( FLAG_1 | FLAG_2 ) ;

// set method 2
byte c = 0 ;
if (flag_bool_1) { c += FLAG_1 ; }
if (flag_bool_2) { c += FLAG_2 ; }

That is a really bad way to do that if your fields are more then 1 bit. The normal way to do it is to use bitmask. So you get
#define FIELD1 0b11100000
#define FIELD2 0b00011100
#define FIELD3 0b00000011
c = FIELD1 & (field << 5) + FIELD2 & (field << 2) + FIELD3 & (field3);
Then to take C and get back the individual fields.
field1 = (c | FIELD1) >> 5;

 

aCynic2

Senior member
Apr 28, 2007
710
0
0
I would zero out a full byte and code the bits into the byte.

I am a bit confused by your request:

But what if I only want to send 3 bits, followed by a string of 5 bytes, lets say. How would I go about doing this?

Then your example shows:

header: 1 byte
flag1: 1 bit
flag2: 1 bit
size:2 bytes
dynamic string: string of varying size
flag 3: 1 bit

Two bits, two bytes, followed by a string of indeterminate size and then another bit.

Whenever you send data of an undetermined size, you'll need a preceeding data type, one or two bytes, that indicates the size of the stream of bytes and perhaps a flag indicating what to treat it as: string, (un)signed byte, (un)signed int, etc.