在我的计算机网络实验室中,我不得不阅读许多包含 IPv4 格式数据包的二进制文件。 Here是IPv4头文件格式。
下面的结构封装了IP头的所有重要部分。
struct ip_header {
uint8_t version;
uint8_t header_length;
uint8_t service_type;
uint16_t total_length;
uint16_t identification;
uint8_t flags;
uint16_t fragment_offset;
uint8_t ttl;
uint8_t protocol;
uint16_t checksum;
uint32_t src;
uint32_t dest;
/* other fields for options if needed */
};
读取二进制文件以获取结构化格式数据的一种方法是逐字节读取文件,然后专门将每个字节字段类型转换为上述结构的相应字段。读取文件不是问题。
我想知道这是否是唯一的方法,或者是否有其他美妙而神奇的方法来实现同样的目的。另外,最近我了解到,在读取这些具有不同大小数据类型的文件时,字节顺序也会产生一些问题。
最佳答案
通常的方法是使用类似fread
bool readIpHeader(ip& buffer, const std::string& filename)
{
auto pFile= fopen(filename.data(), "rb");
if (!pFile) {
return false;
}
auto ok= fread(&buffer, sizeof(buffer), 1, pFile) == 1;
fclose(pFile);
return ok;
}
这会将 sizeof(buffer)
读入地址 &buffer
:它将用文件的内容填充缓冲区; fread
将在成功时返回 1。
正如 Ted 所指出的,您的结构很糟糕。你可以拿https://unix.superglobalmegacorp.com/Net2/newsrc/netinet/ip.h.html作为来源(如果您使用的是 Linux,您很可能可以包含
该文件):
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_char ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
关于c++ - 从包含 IP header 片段的二进制文件中读取结构的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57998948/