Search code examples
csockets64-bitposixportability

Portable way of sending 64-bit variable through POSIX socket


I'm designing custom network protocol and I need to send uint64_t variable (representing file's length in bytes) through socket in portable and POSIX-compliant manner.

Unfortunately manual says that integer types with width 64 are not guaranteed to exist:

If an implementation provides integer types with width 64 that meet these requirements, then the following types are required: int64_t uint64_t

What's more there is no POSIX-compliant equivalent of htonl, htons, ntohl, ntohs (note that bswap_64 is not POSIX-compliant).

What is the best practice to send 64-bit variable through socket?


Solution

  • You can just apply htonl() twice, of course:

    const uint64_t x = ...
    const uint32_t upper_be = htonl(x >> 32);
    const uint32_t lower_be = htonl((uint32_t) x);
    

    This will give you two 32-bit variables containing big-endian versions of the upper and lower 32-bit halves of the 64-bit variable x.

    If you are strict POSIX, you can't use uint64_t since it's not guaranteed to exist. Then you can do something like:

    typedef struct {
     uint32_t upper;
     uint32_t lower;
    } my_uint64;
    

    And just htonl() those directly, of course.