42

Are there net to host conversion functions in C#? Googling and not finding much. :P

bobber205
  • 12,948
  • 27
  • 74
  • 100

3 Answers3

56

IPAddress.HostToNetworkOrder and IPAddress.NetworkToHostOrder?

Each method has overloads for 16, 32 and 64 bit integers.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I assume these 2 methods do the same thing. I note the overloads are only for signed things. Are they safe on unsigned things? – pm100 Feb 20 '14 at 23:44
  • @pm100: You'd expect them to be self-inverses, yes. I wouldn't like to claim that for absolute fact though :) Not sure what you mean by "safe on unsigned things" - you'd have to cast first, at which point it wouldn't be unsigned... – Jon Skeet Feb 21 '14 at 06:47
  • 1
    first - given that a significant number of the things they work on will be things like IP addresses which are unsigned its surprising that there are no overloads for uint32 etc. By 'safe' I mean I am wary of casting signed to unsigned, fiddling with bits and casting back, in general this is a recipe for sign propagation / truncation ,... wiednesses – pm100 Feb 21 '14 at 19:01
  • you should write which one is ntohs and which one is ntohl – SSpoke Jul 30 '15 at 06:08
  • 1
    @SSpoke: Both `ntohs` and `ntohl` would be `NetworkToHostOrder`, but with different overloads for the different sizes. – Jon Skeet Jul 30 '15 at 06:10
  • 2
    The method doesn't always work, and doesn't even tell you that it might fail. I was passing in a `uint` I got from a udp socket, and `NetworkToHostOrder` doesn't accept unsigned (since unsigned numbers are not CLS compliant), and silently converted them to `long`, which is obviously wrong. The solution is to use `BitConverter`. – Leandros Mar 27 '18 at 13:47
  • 2
    @Leandros: It sounds like what you should do instead is just cast to `int`, and cast the result back to `uint`. – Jon Skeet Mar 27 '18 at 13:55
  • @JonSkeet Yes, that works equally well, and is probably a little better, since it'll avoid the allocation of a temporary array. – Leandros Mar 27 '18 at 14:37
5

The System.Memory nuget package includes the System.Buffers.Binary.BinaryPrimitives static class, which includes static methods for dealing with "endianness", including many overloads of ReverseEndianness. On dotnet core, HostToNetWorkOrder is implemented using these ReverseEndianness methods . On a little-endian architecture (which I think is all that support .NET) HostToNetworkOrder and ReverseEndianness methods have identical performance on dotnetcore.

On dotnet framework (net461) however, the performance of calling HostToNetworkOrder is slightly (not quite 2x) slower than calling ReverseEndianness.

I believe that the JIT compiler is actually special casing these methods to invoke the BSWAP x86 instruction. If you exactly duplicate the implementation of the ReverseEndianness(long) method in your own codebase, it will be nearly 4x slower than calling the System.Memory implementation; suggesting there is JIT magic happening.

MarkPflug
  • 28,292
  • 8
  • 46
  • 54
1

@jon-skeet's answer is the most accurate according to your question. However, 'ntoh_' and 'hton_' C functions are extensively used in order to translate between little-endian and big-endian computer architectures.

If your intention is to perform endianess conversions, there is a BitConverter class (static class in the core assembly) that brings you a more suitable way. Specially when:

  • Working with array of bytes (widely used in file or network streams).
  • Detecting endianess architecture of the runtime machine.
  • Converting basic structures beyond integers (booleans, decimals) without typecasting.
  • Your code is not related to network operations (System.Net namespace).
Community
  • 1
  • 1
caligari
  • 2,110
  • 20
  • 25
  • 5
    except that class doesnt have an equivalent function to htonl. I would have to get the bytes, reverse them, then convert back – pm100 Feb 20 '14 at 23:35
  • 1
    `BitConverter` doesn't support any non-native endianness. (At least the built-in one doesn't, Jon or Marc made a more powerful one that does -- but making garbage temporary arrays is still a waste) – Ben Voigt Jul 15 '15 at 16:11