When is htonl (x)! = Ntohl (x)? (Or when converting to and from a network byte is not equivalent on the same machine?)

As for htonl and ntohl . When either of these two lines of code is false.

htonl(x) == ntohl(x); htonl(ntohl(x)) == htonl(htonl(x)); 

In other words, when these two operations are not equivalent on the same machine ? The only scenario I can think of is a machine that does not work with 2 additions to represent integers.

Is the reason significant historical, for clarity of coding, or for something else?

Are there any modern architectures or environments today where these conversions to and from network byte order on the same computer are not the same code in any direction?

+7
endianness sockets
Jul 23 '12 at 17:45
source share
3 answers

I could not find the original draft of the Posix specification, but a recent one found on the Internet has a hint.

The network byte order may not be suitable for processing actual values. To do this, it is more reasonable to store values ​​as regular integers. This is called host byte order. In host byte order:

 The most significant bit might not be stored in the first byte in address order. **Bits might not be allocated to bytes in any obvious order at all.** 

8-bit values ​​stored in uint8_t objects do not require conversion to or from the host byte, since they have the same representation. 16 and 32-bit values ​​can be converted using htonl (), htons (), ntohl (), and ntohs ().

Interestingly, however, the following statement was made in the discussion.

The POSIX standard explicitly requires 8-bit char and two-component arithmetic.

So, this basically eliminates my idea of ​​introducing a machine with one add-on.

But the statement “any obvious order at all” suggests that the posix committee at least considered creating posix / unix on something other than big or small endian. Since such an declaration of htonl and ntohl as differnet implementations cannot be excluded.

So, the short answer is: "htonl and ntohl are the same implementation, but the interface of two different functions for future compatibility with the unknown."

+4
Jul 25 2018-12-12T00:
source share

I wrote the TCP / IP stack for the UNIVAC 1100 universal mainframe many years ago. It was a 36-bit, addressable computer architecture with 1 arithmetic.

When this unit was doing message input / output, 8-bit bytes coming from the outside world would fall into the lower 8 bits of each 9-bit quarter of a word. Therefore, in this system, ntohl () will compress 8 bits in every fourth word down to the lower 32 bits of the word (with the top 4 bits of zero) so that you can do arithmetic on it.

Similarly, htonl () will take the low 32 bits in a word and cancel this operation to put every 8-bit count in the low 8 bits of every 9-bit fourth word.

So, to answer the original question, the ntohl () and htonl () operations in this computer architecture were very different from each other.

For example:

 COMP* . COMPRESS A WORD LSSL A0,36 . CLEAR OUT A0 LSSL A1,1 . THROW AWAY TOP BIT LDSL A0,8 . GET 8 GOOD ONE'S LSSL A1,1 . LDSL A0,8 . LSSL A1,1 . LDSL A0,8 . LSSL A1,1 . LDSL A0,8 . J 0,X9 . . DCOMP* . DECOMPRESS A WORD LSSL A0,36 . CLEAR A0 LSSL A1,4 . THROW OUT NOISE LDSL A0,8 . MOVE 8 GOOD BITS LSSL A0,1 . ADD 1 NOISE BIT LDSL A0,8 . MOVE 8 GOOD BITS LSSL A0,1 . ADD 1 NOISE BIT LDSL A0,8 . MOVE 8 GOOD BITS LSSL A0,1 . ADD 1 NOISE BIT LDSL A0,8 . MOVE 8 GOOD BITS J 0,X9 . 

COMP is the equivalent of ntohl () and DCOMP for htonl (). For those who are not familiar with the UNIVAC 1100 build code :-) LSSL is a "Left Single Shift Logical" register in several positions. LDSL - "Left Double Shift Logical" - a pair of registers on the specified account. Thus, LDSL A0.8 shifts the concatenated registers A0, A1, leaving 8 bits, shifting the high 8 bits of A1 to the lower 8 bits of A0.

This code was written in 1981 for UNIVAC 1108. A few years later, when we had 1100/90 and the C compiler grew up, I started the BSD NET / 2 TCP / IP implementation port and implemented ntohl () and htonl () similarly way. Unfortunately, I have never completed this work.

If you are wondering why some of the Internet RFCs use the term “octet”, it is because on some computers per day (for example, PDP-10, Univacs, etc.) there were “bytes” that were not 8 bits. An "octet" was specifically defined for an 8-bit byte.

+5
Jul 30 '16 at 14:36
source share

Not all cars will have the same specifics, and these methods will take care of this. It is given that the "order of the network" is a large endisiat. If you have a machine with a large end architecture and you run ntohl, the output will be the same as the input (because the continent is the same as the network). If your machine is a small end architecture, ntohl converts data from large to small endian. The same can be said of htonl (if necessary, it converts host data into network byte order). To answer your question, these two operations are not equivalent when you transfer data between two machines with varying degrees of accuracy.

-one
Jul 23 2018-12-17T00:
source share



All Articles