Click to See Complete Forum and Search --> : network byte order question


Energon
02-08-2002, 08:32 PM
Is there a determining factor as to what should be put into network byte order (for a network program)? Like, let's say I've got a chat program, and the user wants to send the message "Hey, I'm 32!", would I parse out the 32, change it to network byte order, and pack it back in, then parse it out at the other end, change it back to native byte order, pack it back in, then print the string? Or is it only something to do if say, I'm writing an accounting program that sends actual numbers to work on?

And when it comes to portability, if I was writing code for a platform that already works in the network byte order, then do I not ever use htonl and so on? Or are those functions smart enough to know, in general, that you shouldn't need to do that conversion?

Thanks for reading... :)

jkm
02-08-2002, 10:29 PM
You want to put _everything_ into network byte order before you stick it on the wire. Since all bytes will be read it the native byte order once they arrive.

If you are running on a big endian system, you don't have to worry, but should _always_ convert to network byte order for portability reasons. The functions are intelligent enough to know what your native byte order is and leave your byte ordering alone if it is already network byte order.

Energon
02-08-2002, 11:08 PM
So would you use htons for characters than? What about structures?

It's odd, I've looked at *some* applications that are networked, but rarely see any consideration given to network byte order, especially concerning things that aren't numbers. Is there a reason for that?

bwkaz
02-09-2002, 02:41 PM
Originally posted by Energon:
<STRONG>It's odd, I've looked at *some* applications that are networked, but rarely see any consideration given to network byte order, especially concerning things that aren't numbers. Is there a reason for that?</STRONG>

I THINK (and someone correct me if I'm wrong) that it doesn't really matter unless one big-endian machine and one little-endian one are talking. Because if both are the same endianness, then regardless of the network byte order, it'll be correct on the other end. However, the packet itself, as displayed with a packet sniffer, would read backwards. For example, if you have 2 Intel boxes talking to each other, then the packets they send will be in the correct order for the Intel hardware, but the network is expecting them the other way around. This doesn't really matter, though, because the receiving program isn't trying to convert anything either, so I think it works.

The only problem is when you have a big-endian box talking to a little-endian box (or vice-versa). In this case, if there's no translation, the big-endian machine sends out a packet in its native order (which happens to be network order, right?), and the little-endian box sees it come in, doesn't convert it, and gets screwed up values. Or the other way around, it works the same way.

I think.

Energon
02-09-2002, 07:52 PM
Hmm... I've been looking at some old source I had lying around for a battle.net bot (just to see if I could make more sense of it than I could a year or so ago), and when it makes a call to send(), there's no consideration taken for network byte order. But, there are Mac clients on battle.net. So is there something going on behind the scenes so that an Intel client doesn't have to convert, but Mac clients can still get into the system?

EDIT - I can't check the Mac Starcraft source, for obvious reasons, so I'm kind of going off that the bot doesn't have to convert, so the server probably doesn't have to convert, so the only the thing that should convert would be the Mac, which is odd (at least in my mind, it's odd).

[ 09 February 2002: Message edited by: Energon ]

Strogian
02-09-2002, 08:23 PM
You only have to worry about Network Byte Order if:
1. You are sending the data across a network (i.e. between two machines in some manner)
AND
2. The datatypes being sent are more than one byte long.

This means that if you are sending a string, you do not have to worry about network byte order. The byte ordering between big-endian and little-endian systems are only different within a single datatype. Therefore, if you are sending an integer over a network, convert it first. If you have an integer which contains the port number of some socket, but you're only using it for local purposes, then do not convert it. If you are sending a character over, do not convert. (I do not even think there is a function to convert a character, is there?)

You should *always* do the conversions if your situation matches the two criteria listed above. Libraries are different for every machine type there is. On a little-endian machine, the conversion functions will be defined to switch all the bytes around to get the data into big-endian form. On a big-endian machine, the conversion functions will be defined to do absolutely nothing. That's called portability. :)

jkm
02-10-2002, 12:18 AM
The real question is, what do you do with a struct? :-)

Energon
02-10-2002, 03:31 PM
So, anything over a byte should be converted... that makes it a bit easier to see what's going on than. I was greping the licq source a bit earlier, and the only places it did conversion was on IP addresses and ports, which makes sense because everything else it should be sending would be a string, where every character is only a byte long. And I believe the same applies to the battle.net bot.

Would you, in the case of a struct, just do conversions on types within the struct rather than the entire struct itself? And then send just the parts of the struct necessary to save bandwidth?

Strike
02-11-2002, 01:41 AM
Originally posted by Energon:
<STRONG>Would you, in the case of a struct, just do conversions on types within the struct rather than the entire struct itself? And then send just the parts of the struct necessary to save bandwidth?</STRONG>
As long as you are consistent on both ends, it should be okay. I don't know what the common practice is, however.

Strogian
02-11-2002, 07:47 AM
Originally posted by Energon:
<STRONG>Would you, in the case of a struct, just do conversions on types within the struct rather than the entire struct itself? And then send just the parts of the struct necessary to save bandwidth?</STRONG>

Yeah, that's probably what you would want to do. I'm not exactly sure how sending a whole struct would work (i.e. what it would do with the padding bytes).