uint16_t在char数组中

时间:2016-04-09 09:38:41

标签: c tftp

对于学校项目,我必须在C中开发TFTP服务器。 我必须在这样的char数组中构建一个数据包:

 2 bytes    2 bytes    n bytes
+--------+-----------+--------+
|  CODE  |  Block #  |  Data  |
+--------+-----------+--------+

以下是我构建此数据包的方法:

int tftp_make_data(char *buffer, size_t *length, uint16_t block, const char *data, size_t n) {
    memset(buffer, 0, *length);
    *length = 0;
    *(buffer) = DATA;
    *length += sizeof(uint16_t);
    *(buffer + *length) = block;
    *length += sizeof(uint16_t);
    memcpy(buffer + *length, data, n);
    *length += n;

    return 0;
}

此函数使用数据包内容填充buffer,并使用数据包的大小填充length。 如果block低于128,则此工作正常。如果它比128更好,则变为-128。

你能帮助我吗?

1 个答案:

答案 0 :(得分:3)

除非某个字节大小为一个字节,否则您无法将其分配给*buffer。这两项任务都不正确:

*(buffer) = DATA;
*(buffer + *length) = block;

撰写uint16_t时,请使用memcpy

uint16_t dataToWrite = ...;
memcpy(buffer + *length, &dataToWrite, sizeof(uint16_t));

您还没有完成,因为您需要决定分配dataToWrite的内容。如果你这样做

uint16_t dataToWrite = block;

通过线路发送的数据将采用特定于硬件的顺序,这种情况永远不会发生。相反,您需要使用hton-family functions之一将您的号码转换为网络格式:

uint16_t dataToWrite = htons(block);
  

我在同一台机器上检查它,只需

printf("block : %d\n", packet[sizeof(uint_16)]);

这是不正确的,原因与作业相同:packet[sizeof(uint_16)]从位置存储的int / unsigned int值中生成charuint8_t sizeof(uint_16),它也忽略了另一个字节。

要解决此问题,您需要再次使用memcpy。当然,如果您在写作方使用htons,则需要在打印前使用ntohs

uint16_t dataToPrint;
memcpy(dataToPrint, &packet[sizeof(uint16_t)], sizeof(uint16_t));
dataToPrint = ntohs(dataToPrint);
printf("block : %u\n", dataToPrint);