序列化:char和uint32_t的大小

时间:2016-07-01 15:07:40

标签: c networking serialization

我有多个问题。

  1. 每个系统上char的大小总是1(Byte)吗?
  2. 每个系统上uint32_t的大小是否总是4(Byte)?
  3. 我写了两个很小的函数来序列化我的结构,但是我不能告诉你这是不是一个很好的方法。

    struct udtpackage{
        char version;
        bool eof;
        uint32_t data_size;
        uint32_t encrypted_size;
        char data[BUFFERSIZE+16];
        char hmac[64];
    };
    
    void serialize (udtpackage package, unsigned char* buffer){
        uint32_t tmp;
    
        memcpy(&buffer[0], &package.version, 1);
        (package.eof) ? (buffer[1] = 0xFF) : (buffer[1] = 0x00);
        tmp = htonl(package.data_size);
        memcpy(&buffer[2], &tmp, 4);
        tmp = htonl(package.encrypted_size);
        memcpy(&buffer[6], &tmp, 4);
        memcpy(&buffer[10], &package.data[0], BUFFERSIZE+16);
        memcpy(&buffer[10+BUFFERSIZE+16], &package.hmac[0], 64);
    }
    
    void deserialize (udtpackage* package, unsigned char* buffer){
        uint32_t tmp;
    
        memcpy(&package->version, &buffer[0], 1);
        (buffer[1] & 0xFF) ? (package->eof = true) : (package->eof = false);
        memcpy(&tmp, &buffer[2], 4);
        package->data_size = ntohl(tmp);
        memcpy(&tmp, &buffer[6], 4);
        package->encrypted_size = ntohl(tmp);
        memcpy(&package->data[0], &buffer[10], BUFFERSIZE+16);
        memcpy(&package->hmac[0], &buffer[10+BUFFERSIZE+16], 64);
    }
    

1 个答案:

答案 0 :(得分:4)

  1. 是。 char的大小始终为1.这并不意味着每个字节有8位。

  2. 没有。例如,该实现可以定义每字节32位,
    那么uint32_t的大小将为1.如果是这种情况,将不会定义某些固定宽度类型。

  3. 这是一个潜在的问题:

    memcpy(&buffer[2], &tmp, 4);    
                             ^
    

    正如我在第二点中提到的,代码应该是:

    memcpy(&buffer[2], &tmp, sizeof(tmp));
                             ^
    

    还应该修复缓冲区偏移,否则你可能会浪费内存:

    memcpy(&buffer[6], &tmp, 4);
                   ^