Send data with winsock

Started by
29 comments, last by hplus0603 19 years, 4 months ago
Howdy yall, I'm able to send messages back and forth via int send( SOCKET s, const char* buf, int len, int flags ); I'm able to make a little chat program with this, however...We are trying to send floats from server to client and vise versa. How is this possible when the send command expects a character buffer?
Advertisement
a char* is just a block of memory. really, they should have called it 'byte' instead of 'char'. you can copy any POD type into a char array using memcpy. ex:

//a 4 byte bufferchar buffer[4];float some_float = 34.3f;memcpy(buffer,&some_float,sizeof(some_float));send(..,(const char*)buffer,4,..);


you can stuff as much data as you want into a char array. be it 100 floats or just 1..
FTA, my 2D futuristic action MMORPG
So, your char array is 4 because you need one for each character of the float...34.3f?

And if that is the case then what if you have a float 23.3434523 and then use memcpy to put it into a char array that only hold 4 chars...will it truncate for you?

And last question...once the server sends the char*, how do you save it on the client. Would you put what you recieve in a char buffer or can you just save it directly to a float?
well, to be honest i'm not an exactly an expert in this area, but..

a character is really just one byte of memory. a float is 4 bytes. just think of a character array as a block of memory. this means you can copy a float, or any other type for that matter, into this block of memory.

no matter what your float's value is, it will only take up 4 bytes. the amount of memory it uses does NOT have to do with how many numbers are in the float. 34.3 and 23.3434523 both take up 4 bytes of memory.

when you receive this char buffer on the other end, yes, you can copy it directly into a float or whatever type it should be. for example, if your receiving the char buffer with a float from my first example, it would look like this:

float my_float;memcpy(&myfloat,packet_data,sizeof(my_float));
FTA, my 2D futuristic action MMORPG
the more precision you use, the more bytes needed. float use 4 bytes, double use 8 byte if not mistaken, mayb 6? check it :P
so it is your design issue to decide either use 4 byte char or 8 byte char to store floating point value.
hope this help.

regards,
chung
//Sender
float val = 35.454588f;
char buffer[4];
memcpy(buffer, (char*)&val, 4, 0);
send(sock, buffer, 4, 0);


//Receiver
char buffer[4];
float val;
recv(sock, buffer, 4, 0);
memcpy((char*)&val, buffer, 4);
val = val + 1.0f; //val = 35.454588 + 1.0 = 36.454588


Note: if you increase Sender's val precision to 35.4545889f, and still using 4 byte float,the system will truncate and store 35.454588 only. unless you use double, and increase buffer to 8 bytes instead of 4.


regards,
Chung


instead of memcpy i usually like to do the following:

char arr[4];
float x = 3.14159f;

*(float*)arr = x;

to unpacket it

float y = *(float*)arr
Use the power of the compiler to do your dirty work.

This trick is usually about 5 times faster :)
If all you want to do is send one float then just use:

send(sock, (char *) &f, sizeof(f), 0);

There's no need to memcpy anything. And for gods sake please done hardcode the length to be 4. That's why we have sizeof.

People get hung up on socket stuff using char* everywhere. It's just a holdover from the bad old days when C had basically no type checking. If it could be redone today they would be void* or perhaps u_char* instead.

Actually to be technical you might have to buffer up the float first - if you're doing endian conversion or float-point format conversion. The former depends on your wire protocol and if you only care about Windows then there's no reason to not using native (little-endian) on the wire. The latter is pretty much irrelevant these days.
-Mike
So you only use memcopy when you want to send more than one thing at once?

I'm not really grasping this concept. If you only send one float you don't use memcopy but if you have more than one, why not just repeat the code without memcopy to do it multiple times?

And also, does memcopy append the data to the end of the char array?, because if that were true, then how exactly would you access all the data in the array once its recieved if it is a different amount of bytes? will each memcopy put the data into a new index in the buffer array?
Quote:Original post by Steers
So you only use memcopy when you want to send more than one thing at once?


i cannot think of any real situation in which you only want to send a single piece of data. at the very least, you need an indentifier to know what that data means. how else would you know how to parse a packet?

Quote:
I'm not really grasping this concept. If you only send one float you don't use memcopy but if you have more than one, why not just repeat the code without memcopy to do it multiple times?


you would want to group your data into a single packet, with a way to indentify what this packet means. otherwise, your just sending blind data out. how will the receiver know how to parse it? what does that data mean?

Quote:
And also, does memcopy append the data to the end of the char array?, because if that were true, then how exactly would you access all the data in the array once its recieved if it is a different amount of bytes? will each memcopy put the data into a new index in the buffer array?

memcpy will write the data to the point in the array you pass it. in the given examples, we write it at the very begining of the array. however, you can write it in the middle or at the end of the array as well. you should really google for tutorials on arrays and pointers to brush up on this.

anyway, maybe an example will help you understand. lets say we are on the client and want to build a packet which we will send to the server our X and Y position. so, this packet needs a way to say "hey, this is our position", and then our position. so, it would look something like this:

//this message is 9 bytes long. 8 bytes for our position and 1 byte MSGID
char buff[9];

const unsigned char MSGID_MY_POSITION = 0;
float x = 40.3f;
float y = 35.2f;

//write the ID into the packet
memcpy(buff,&MSGID_MY_POSITION,1);

//write the X position
memcpy(buff+1,&x,sizeof(x));

//write the y position
memcpy(buff+5,&y,sizeof(y));

send(..,buff,9,..);

on the receiving end, you read the first byte to find out what kind of message this is. now that you know that its a MY_POSITION message, you know that the next 8 bytes are my x/y position.
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement