我的目標是通過以網絡字節順序以64位無符號整數開頭的網絡發送數據報。所以首先我用宏的數量轉變爲大端:將64位無符號整數轉換爲字符緩衝區C
#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
#define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
然後,我把它序列化到一個緩衝區:
unsigned char * serialize_uint64(unsigned char *buffer, uint64_t value) {
printf("**** seriializing PRIu64 value = %"PRIu64"\n", value);
int i;
for (i = 0; i < 8; i++)
buffer[i] = (value >> (56 - 8 * i)) & 0xFF;
for (i = 0; i < 8; i++)
printf("bufer[%d] = %x\n", i, buffer[i]);
return buffer + 8;
}
然後我反序列化與
uint64_t deserialize_uint64(unsigned char *buffer) {
uint64_t res = 0;
printf("*** deserializing buffer:\n");
int i;
for (i = 0; i < 8; i++)
printf("bufer[%d] = %x\n", i, buffer[i]);
for (i = 0; i < 8; i++)
res |= buffer[i] << (56 - 8 * i);
return res;
}
似乎爲小整數工作但以下測試代碼無法正常工作:
uint64_t a = (uint64_t) time(NULL);
printf("PRIu64: a =%"PRIu64"\n", a);
uint64_t z = htonll(a);
uint64_t zz = ntohll(z);
printf("z = %"PRIu64" ==> zz = %"PRIu64" \n", z, zz);
unsigned char buffer[1024];
serialize_uint64(buffer, z);
uint64_t b = deserialize_uint64(buffer);
uint64_t c = ntohll(g);
我得到
a = 1494157850
htonll(a) = 1876329069679738880 ==> ntohll(htonll(a)) = 1494157850
**** seriializing PRIu64 value = 1876329069679738880
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
*********
*** deserializing buffer:
bufer[0] = 1a
bufer[1] = a
bufer[2] = f
bufer[3] = 59
bufer[4] = 0
bufer[5] = 0
bufer[6] = 0
bufer[7] = 0
===> res = 436866905
c = 6417359100811673600
好像緩衝區沒有捕捉較大的那個數...
編輯:它適用於32位所以'2,147,483,647',但它崩潰'2,147,483,648' – micsza