how does microsoft do this?

Started by
12 comments, last by fireking 21 years, 6 months ago
microsoft''s direct x direct play 8 allows you to send a structure as your data, how do they do that? --Fireking Owner/Leader Genetics 3rd Dimension Development
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
Advertisement
I''m doing the same thing with just winsock 1.1. Its really easy, just have your struct, then when you send it just send like this:

send(sock, (char *)mystruct1 ...)

then on your recv just cast it into an identical struct

mystruct struct1;
recv(sock, (char *)mystruct1 ...)
and you then can send a struct
wow, C++ is so godly, thanks

--Fireking

Owner/Leader
Genetics 3rd Dimension Development
--FirekingOwner/LeaderFiregames Development &Blackdragon Studios
I love c++. Just reading that made my heart warm.
Sending structs that was is kind of icky, and won''t work if you want to make your program portable.

Structs are usually padded and aligned by compiliers, so their size and alignment is not always what you would expect.

For example:

struct X
{
char a;
int b;
};

Might have a different size depending on the platform and compilier used. Generally sizes are rounded to the nearest power or multiple of 2.

So sizeof(X) might be 5 on some systems, or 8 on others.

Also sending structs this way won''t work at all if one system is little endian and the other is big endian. You would be better off using some sort of Pack/Unpack method for each struct you want to use, making use of the ntoh* and hton* functions.

E.g.
void PackX(X x, void *buffer)
{
*((char *)(buffer)) = x.a;
*((int*)(buffer + 1)) = htonl(x.b);
}

void UnpackX(X &x, void *buffer)
{
x.a = *(char *)(buffer);
x.b = ntohl( *((int *)(buffer + 1));
}

So you would pack your struct before you send it, and unpack it after your received it.

E.g.

X x;
char message[SIZE];
PackX(x, message);
send(message):

and

X x;
char message[SIZE];
recv(message):
UnpackX(x, message);
quote:Original post by Anonymous Poster
Structs are usually padded and aligned by compiliers, so their size and alignment is not always what you would expect.


one would assume that since he''s writing the program sending data,
there''s a really good chance he''s also writing the program that
recieves it.. since structs are usually custom.
and based on that fact, one would assume that he''s compiling
using the same compiler and platform.
and based on that fact, the alignment and padding should
always be what he expects, right?

-eldee
;another space monkey;
[ Forced Evolution Studios ]

::evolve::

''In C we had to code our own bugs. In C++ we can inherit them.''

-eldee;another space monkey;[ Forced Evolution Studios ]
unless the server runs on linux compiled with gcc and the client runs on win32 compiled with vis c++.....
The Solution.

Don''t listen to me. I''ve had too much coffee.
I think the AP was just pointing these things out for future reference, incase he does deside to run a server on a different platform/compiler... I''m sure you''ll agree its better to have all the infomation to begin with rather than half the infomation and wonder why it doesnt work later?

Personaly, I think a pack/unpack function is a very good idea, as it would allow you to save the amount of data being sent, for example if you had a number which could only used a max of 24 bits, and 8 bool values, you could back them all into one 32bit buffer and send, instead of hoping the underlieing stack/API might work some magic for u
(can you tell I''ve been coding the HL SDK recently? hehe)
(FYI I''m the Anon poster who put the packed stuff there)

The solution linked to by Sneftel (turning off padding) will not work in all cases so it isn''t the best solution. Padding will not solve endian issues.

There is a reason that structs are padded by the compilier: to optimize access to data members.

Without padding, each access to the struct could entail a performance hit, (extra instructions, etc.). Since sending over the network is already a slow operation the extra effort of packing/unpacking isn''t much of an impace. However, the extra instructions required to access unpadded data, especially in a tight inner loop, could cause a noticible performace loss. (Probably not, but it could).

Now, if you are just learning about networking, then you can worry about this stuff later. Also, if you never intend to port to a different CPU architecture, you can use the Sneftel''s solution.

This topic is closed to new replies.

Advertisement