Packet Data Question

Started by
14 comments, last by genovov 24 years, 2 months ago
I am also working on a client/server game. When i did my readup on the subject however, I found that you only need to convert to network byte order and then send [like you say]. But you should be able to use sizeof()s. I mean, a short int on an intel is the same size as a short int on an alpha [isn't it?]. I guess if you send a 64 bit var to a system that can't handle it, then there'll be problems, but I don't see a situation where you'd need to do that. If it's neccessary though, you can code the <64bit client to handle this.

Thus, no, converting to ascii is not needed.

NOTE: this is a combination from what I've read and my own logic/knowledge.

If I am wrong, correct me

~Queasy.

Jonathan Makqueasy gamesgate 88[email=jon.mak@utoronto.ca]email[/email]
Advertisement
You certainly should send binary data over ASCII, that's just foolish. You will have to make sure that data sizes match on different platforms. In C, you set up typedefs for specific size data types, then use those throughout your program so that when you port it all you have to do is make sure those typesdefs are the correct size. Also, you have to make sure that your compiler is not automatically padding structures with extra bytes - another source of incompatibilities between platforms.

- Splat

Simple types such as shorts, ints, longs, etc can have different sizes on different platforms. For instance, last time I programmed a mac (5 years ago!), an int was 16 bits. Under Windows, an int is 32 bits.

What I do is create a header file in which a define my own fixed sized types...

typedef char int8;
typedef short int16;
typedef int int32;
typedef long long int64;

Then if I need to port to another platform I just need to change this header.

The only other thing that really differs between platforms is the byte order. There are some useful functions in winsock2.h (htons, htonl...) for swapping between native and TCP/IP byte ordering. These functions are also in BSD sockets so they will work with Linux. Don't know about other platforms though!

I was under the impression that 64 bit alphas were only able to address data aligned on 32 bit boundries. I assumed that this would require padding 'byte' and 'short int' vars to 32 bit. I suppose that is not necessarily true. But if data type sizes were always the same, on all systems, why use sizeof() for base data types?

Does anyone know if there is a network byte order function for floats? I haven't seen any mention of such beast.

I was reading some docs on the design of XShipWars, and they use ascii text for their packets, with the claim that it solves porting issues...

But I'd much prefer to go with binary data, as it's more compact, and you can compute the size of a packet based on the data type sizes.

Thanks for the reply : )

Another quick question for Splat:

I'm aware that most (all?) c/c++ compilers pad structures to 2/4/8 byte boundries, to speed memory access. Do compilers usually provide a way to prevent this from occuring, for specific structures? When I was using DJGPP, there was a #pragma you could use for individual structs, and I believe the gnu compiler has a command-line directive to prevent padding for ALL structures. Is there a similar directive or pragma for individual structs for gnu? What about MS Visual C++?

Obviously, this could greatly simplify my network code, and still prevent sending padding over a socket.

Thanks
-g

[This message has been edited by genovov (edited November 17, 1999).]

Ye ole #pragma for Visual C++ packing rules:

#pragma pack(push, original)
#pragma pack(1)

...

#pragma pack(pop, original)

- Splat

I think IEEE floats and doubles are standardized, so platform issues _shouldn't_ exist. Never tried though.

- Splat

The four biggest guidelines for writing portable data structures:

* Define explicit data types (int8, int16, int32) and avoid implicit types like int.
* Align data to natural boundaries (16 bit types at even addresses) and avoid implicit padding by the compiler (even if you have to add your own padding).
* Pick a byte ordering and stick to it. I prefer big endian, but it's trivial to just define macros that do the right thing by platform and use them everywhere.
* Translate the data once, as it's imported, recv'd, or read and exported, sent, or written. All data structures in memory should be in native format, all data on disk should be in portable format.


Matt Slot / Bitwise Operator / Ambrosia Software, Inc.
Splat: IEEE IS standard, but you still need to be aware of little/big endian issues. (I.e. an 8-byte IEEE double precision floating point number looks different when stored in little endian compared to big endian...).
<b>/NJ</b>
Niels: True, true. Endian differences are always something you have to deal with.

- Splat

This topic is closed to new replies.

Advertisement