Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


Packet Data Question


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
15 replies to this topic

#1 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 01 December 1999 - 07:35 PM

I've been working on a small client/server multiplayer game in linux, with the intent to porting the client to other os's at a later date. Keeping portablity in mind, does anyone have any suggestions on how to send data between the client and the server. I was initially sending binary data, thinking that it would make for smaller packets, but then realized that writing sizeof(foo) bytes on one machine and reading sizeof(foo) bytes on another machine wouldn't work, if their internal representations are different (alphas for instance). Also, am I correct in assuming that endian-ness would also render this method useless, without conversion to network byte order when sending and recieving?

The only other option left seems to be converting all data into ascii text strings, sending it, and then converting the text back into integers/floats ect. Would printf()/scanf() do the trick? Does anyone know how this is done 'in the real world'?

Thanks a bunch

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


Sponsor:

#2 Queasy   Members   -  Reputation: 157

Like
Likes
Like

Posted 17 November 1999 - 01:47 PM

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.


#3 Splat   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 02:05 PM

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


#4 Alastair   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 02:09 PM

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!


#5 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 02:29 PM

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 : )


#6 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 02:46 PM

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).]


#7 Splat   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 03:13 PM

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

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

...

#pragma pack(pop, original)

- Splat


#8 Splat   Members   -  Reputation: 122

Like
Likes
Like

Posted 17 November 1999 - 03:14 PM

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

- Splat


#9 fprefect   Members   -  Reputation: 122

Like
Likes
Like

Posted 18 November 1999 - 06:43 PM

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.




#10 Niels   Members   -  Reputation: 122

Like
Likes
Like

Posted 18 November 1999 - 10:23 PM

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...).

#11 Splat   Members   -  Reputation: 122

Like
Likes
Like

Posted 19 November 1999 - 10:33 AM

Niels: True, true. Endian differences are always something you have to deal with.

- Splat


#12 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 23 November 1999 - 08:31 AM

Well, thanks to all who replied. I think I've got all the information I need to proceed with this part of the network coding : )

I've got a new question though. I've read in numerous places, that the UDP/IP protocol offers faster transfer times (smaller headers, and no packet ordering or guarantee of reciept) than TCP/IP. I've read that 'packet' loss can be as high as ~20%. My question is what exactly determines what data will be in a 'packet'. Does every call to write() on a socket create a new packet? I've heard there is an algorithm (forget the name) that is used to buffer TCP/IP data for optimum efficency. Is this algorithm also applied to UDP/IP transfers? I ask because I want to know if I have to deal with cases where I will recieve only the start or the end of a message that I've sent, or if i can insure that each of my networking messages exist in one and only one packet.

-g


#13 fprefect   Members   -  Reputation: 122

Like
Likes
Like

Posted 01 December 1999 - 07:35 PM

UDP is simply a packet on the wire, and doesn't perform any sort of reliability or flow control (Nagle's algorithm). UDP packet headers may be simpler, but can't take advantage of TCP header compression.

UDP packets are usually sent with sendto() and recv'd with recvfrom(), so that you can specify the remote address -- since there is no actual connection between the hosts. Each call to sendto() sends a single packet, and each call to recvfrom() reads one in (if available).

UDP is nice if you want fine control over the retry and flow control algorithms (games have different needs than FTP software), but if you aren't network-savvy, then it's easy to ruin your performance instead of improving it.


#14 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 13 February 2000 - 11:45 AM

I''m still a bit confused . Maybe a quick example will clarify my question.

Two processes are sending packets to each other, with open UDP sockets. Process1 has sent 3 16-byte packets since Process2 last called recvfrom(). Assuming no packets were droped, and that all three have arrived, what will happen when Process2 calls recvfrom again, with a maxlen parameter of 48(3x16)?

Will it read in 16 bytes(1 packet), or 48(all three)?

Thanks,

-genovov

#15 fprefect   Members   -  Reputation: 122

Like
Likes
Like

Posted 13 February 2000 - 01:00 PM

recvfrom() will only return 1 UDP packet, no matter how many are queued up. It also will truncate the packet if the buffer you pass is too small -- you lose the rest of the packet.

recv() will try to fill the buffer you pass it with TCP data, regardless of how it was sent (1 large packet or 50 small ones). It''s a "stream" format, so all the data just runs together, and it''s up to you to accumulate and break it into messages.

#16 genovov   Members   -  Reputation: 122

Like
Likes
Like

Posted 13 February 2000 - 01:06 PM

Thanks for your quick response

-genovov




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS