对于学校项目,我必须在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。
你能帮助我吗?
答案 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
值中生成char
或uint8_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);