2

I've been playing with C sockets recently, I managed to exchange files between a client and server. However I stumbled upon this problem: when sending the file size between my mac (64 bit) and a raspberry pi (32 bit), it fails since size_t is different between the two. I solved by switching to uint64_t.

  • I'm wondering, is this a bad practice to use it in place of size_t, which is defined in all prototypes of fread(), fwrite(), read(), write(), stat.size?
  • Is uint64_t going to be slower on the raspberry pi?
Matteo
  • 413
  • 1
  • 3
  • 9
  • 3
    I'd say no, because the `intxx_t` types are guaranteed to be the same size everywhere, while `int`, `long`, `size_t` etc.. are not. – alain Nov 17 '16 at 11:51
  • 2
    You can also send a string and forget about such problems. – 2501 Nov 17 '16 at 11:52
  • 2
    Depending on how portable you want this to be, you'll also have to consider endianess. In all forms of data communication, the size and format of the data you send should be _as specified by the communication protocol_. – Lundin Nov 17 '16 at 12:27
  • @Lundin So i should use htonl() when sending and ntohl() after receiving, right? – Matteo Nov 17 '16 at 12:49
  • No, you should write down a specification over what data you send, how large it is, what signedness it has and what endianess it uses. Then every program, be it client or server, has to adapt to comply with the spec. – Lundin Nov 17 '16 at 14:09
  • @Lundin The only integer i need to send is the size of the file, which I gather using stat. – Matteo Nov 17 '16 at 14:18
  • Also, htonl operates on uint32_t, not uint64_t. – zwol Nov 17 '16 at 22:10
  • 1
    There are plenty of 64-bit implementations of `htonl()` and `ntohl()` available if you look around. – Remy Lebeau Nov 17 '16 at 22:34
  • @RemyLebeau Sure, bswap64 is a thing, but it isn't _called_ htonl/ntohl. – zwol Nov 18 '16 at 20:19
  • @zwol `bswap64()` is not the same thing as `htonl()`/`ntohl()`. A more accurate equivilent would be `htobe64()`/`be64toh()` instead. – Remy Lebeau Nov 18 '16 at 22:05

1 Answers1

3

This is not only good practice, but ultimately a necessity. You can't exchange data between different computers of different architectures, without defining the format and size of your data, and coming up with portable ways to interpret it. These fixed-width types are literally designed for the purpose.

Will it be slower to use a uint64_t than a uint32_t on a 32-bit platform? Probably, yes. Noticeably? Doubt it. But you can measure it and find out.

Don't forget to account for differences in endianness, too.

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055