Sign in to follow this  


Recommended Posts

Hey, I have a question that I can't so much find an answer to yet, so hopefully someone here will be able to answer me. I have to explain a bit firstly though. With winsock you send data as a character array. If you needed to send an integer in this character array though, you could convert it to ascii text. Example -> "Joe fires a bazooka 6324567 miles". As you can see this is a 34 character long string, hence it would take up 34 bytes. But there is a problem with this ... 6324567 is an integer value, and it only should take up 4 bytes. In ascii form ( which it would currently be in ) it takes up 7 bytes, not 4 -> as you can see this is a waste. So if each character takes up 1 byte, and an integer takes up 4 bytes, it would seem logical that an integer could be stored in a character array of size 4, no? Would anyone know how to convert an integer into a character array of size 4? Thanks, AA

Share this post

Link to post
Share on other sites
You can do it with casting but I think the following is more readable (And this is pretty close to what happens anyway once compiled)

char my_packet[sizeof(int)];
int my_integer = 12345;

// copy 4 bytes of data (an entire integer) from my_integer
// to my_packet
memcpy(my_packet, &my_integer, sizeof(int));

// get it back out
memcpy(&my_integer, my_packet, sizeof(int));

// *** for multiple integers in one packet
char my_packet[sizeof(int) * 3];
int my_integer1 = 1, my_integer2 = 2, my_integer3 = 3;

// copy the 3 integers to the packet
memcpy(&my_packet[0], &my_integer1, sizeof(int));
memcpy(&my_packet[4], &my_integer2, sizeof(int));
memcpy(&my_packet[8], &my_integer3, sizeof(int));

// grab them back out
memcpy(&my_integer1, &my_packet[0], sizeof(int));
memcpy(&my_integer2, &my_packet[4], sizeof(int));
memcpy(&my_integer3, &my_packet[8], sizeof(int));

Share this post

Link to post
Share on other sites
I could be a little confused with what you're asking, but in your case I'd do something like the following:

char szFinalMessage[ x ];
int iDistance = 35000;
sprintf( szFinalMessage, "Joe fires a bazooka %i miles", iDistance);

Output would be:

Joe fires a bazooka 35000 miles

As well, one other thing to note, if you can avoid casting integers, shorts, etc. to ascii do it at all costs. If you know a value will never be greater than say 32,000, I simply packed it into my message as follows:

szData[ iCurrentIndex ] = ( m_iDistance & 255 );
szData[ iCurrentIndex ] = ( ( m_iDistance >> 8 ) & 255 );

This will write out the first 8 bits then the next 8 bits to the message, thus shrinking the amount of space required for your integer by half. If writing out a full integer you could simply:

szData[ iCurrentIndex ] = ( m_iDistance & 255 );
szData[ iCurrentIndex ] = ( ( m_iDistance >> 8 ) & 255 );
szData[ iCurrentIndex ] = ( ( m_iDistance >> 16 ) & 255 );
szData[ iCurrentIndex ] = ( ( m_iDistance >> 24 ) & 255 );

This will grab all 32 bits and write them out if their current mask is 1 (since 255 = 0x11111111 in Binary). To reconstruct it on the other side simply do the following:

int iTemp = ( szData[ iCurrentIndex ] +
( szData[ iCurrentIndex + 1 ] << 8 ) +
( szData[ iCurrentIndex + 2 ] << 16 ) +
( szData[ iCurrentIndex + 3 ] << 24 ) );

// now iTemp = m_iDistance

As for writing strings you could use:

memcpy( &szData[ iCurrentIndex ], szSomeString, sizeof( szSomeString) );
iCurrentIndex += sizeof( szSomeString );

That last bit could be incorrect I'd have to double check when I get home exactly how I handled this but I think I got the generate idea pretty close here. I may have used strlen() in place of sizeof() but I can't be 100% certain.

Hope this answers your question and helps to point you in the right direction.


Share this post

Link to post
Share on other sites
The most efficient way to send them would be either through DarkHamster's pointer method (best method), or Permafried's slightly more round about method of manually splitting data into 8bit components. Permafried's method becomes more important when you want to start maximizing the amount of information transmitted - for example you can stuff two 1-16 integer values into one character using bit shifts and masks. Using memcpy will also work, but you have to understand that the compiled code will be less effecient. In general (depending heavily on what kind of CPU, what kind of loop it is in, etc) you need to be working with about 8-10 bytes of data at a time before memcpy becomes more effecient then just sticking the bytes in yourself. Certainly if you are pushing around 32bit values the pointer method is faster.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this