Skip to main content
gamedev.net
🔒 Locked

Send struct data.

Started by zyron Jun 26, 2004 at 5:08 PM 8 replies 1.6k views
Original Post
zyron
zyron
Hi there, I have done an simple server that sends id, pos to the client that are connected it looks like this. struct CSend_pData { char message[1024]; int id; float xPos; float zPos; }; CSend_pData pData; strcpy(pData.message, "welcome"); pData.xPos = 10.0f; pData.zPos = 15.0f; pData.id = 5; When I have set the struct vaiables to something I send the data to the client like this. send(sock, (char*)&pData, sizeof(CSend_Pdata), 0); then i recv the data in the same way but I only the the message not the ohters in the struct, do I need to send the struct data on an ohter way? give me some tips. EDIT : is this an bad way to handle the data?
Pipo DeClown
Pipo DeClown
This is the correct way to send and receive data. But to handle data, not really. You should really write a system instead of this C-style code, you'll get confused in no time if you continue adding sends and recvs.

Design your program before coding it. Whenever I don't, I fail!
SiCrane
SiCrane
What protocol are you using? It could be that the entire packet isn't getting sent. What are the return value of send() and recv() when you send this data?
C-Junkie
C-Junkie
This isn't a bad way, but when you recv() on the other side, pay attention to the return value.

You MUST have recv()'d the whole sizeof( that struct ) before you tray and use the data in the struct.

My guess is that (something like) 50 bytes arrive, and recv() returns jsut those 50, and you think you have the whole 1024+howeverManyElseTheStrructIs
zyron
zyron
C-Junkie allright, can i do something like this then?


struct Send_CPlayer_Data
{
char Message[1024];

int id;
float xPos;
float zPos;

};

Send_CPlayer_Data Send_Pdata;

float CalcSize = sizeof(Send_CPlayer_Data)+ sizeof(Send_Pdata.Message)+
sizeof(Send_Pdata.id)+
sizeof(Send_Pdata.xPos)+
sizeof(Send_Pdata.zPos);

send(sock, (char*)&Send_Pdata, CalcSize, 0);

:S
C-Junkie
C-Junkie
The way you SENT the structure was absolutely fine. You have to be careful when recieving it.

Here's pseudo code that recieves the struct on the other end:

thatstruct s;int bytes = sizeof(s);int total = 0;int ret;while(bytes >0) {  ret = recv(socket,((char*)(&s))+total,bytes,0);  bytes -= ret;  total += ret;}// NOW, s is recieved
zyron
zyron
Thx!
CoreMeltdown
CoreMeltdown
Quote:
Original post by C-Junkie
The way you SENT the structure was absolutely fine. You have to be careful when recieving it.

Here's pseudo code that recieves the struct on the other end:

*** Source Snippet Removed ***


@C-Junkie: your code is absolutely right, but, according to how sockets work, it is redundant, because the recv() must block until all bytes required to receive have been received, unless you sent data in multiple times.

For example, if you send 10 blocks, 10 bytes each, your first recv(..., 100, ...) will receive only 10 bytes (and returns this value), so you have to call recv() 10 times to receive all data. BUT if you send a data block X bytes long, your corresponding recv(..., X, ...) will block until all X bytes of data are received or until some error occurred.

So, if he's calling a send(..., sizeof(HisStruct), ...) and a recv(..., sizeof(HisStruct), ...) it must work if his socket layer implementation complies with Berkeley standards (as it is supposed to).

Regards.
zyron
zyron
Your right, I only get the recv one time so it doesent recv all the bytes, it only recv a little bit then it block and wait for an ohter income fom the server. so how do I recv all the bytes that I need? send on an ohter way or recv on an ohter way?

EDIT : now im slow in my brain.
hplus0603
hplus0603
Quote:
the recv() must block until all bytes required to receive have been received


That's not true. Fragmentation, signals, buffer sizes, windows, or the phase of the moon may cause recv() to return less than requested number of bytes, depending on sockets implementation specifics and socket options in effect. This is for TCP sockets.

If you're using UDP sockets, then you will get exactly zero or one datagram through recv(). If your buffer wasn't big enough, whatever was left in the datagram gets lost in the ether; you can't get it back with a second recv(), because that second recv() will get the next datagram.

May I suggest that sending a 1024 byte buffer across the wire for each message you send is terribly inefficient? If someone's using a modem, you'll only get 3 of those messages across per second or so, give or take. And you're very unlikely to ever actually send a message that big. If you still want the simple fixed-size struct, use something like 128 bytes -- if you need to send something bigger, just chop it up and send it in multiple messages. Else look into sending length+data packets instead, where only used data is actually sent.
enum Bool { True, False, FileNotFound };

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.