c++ - 如何提高文件读取性能?
问题描述
我创建了一个通过 fread 函数读取和分析 pcap 文件的 c++ 程序。
它是一个读取pcap文件的全局头,读取pcap头,并通过指定每个协议头结构提取特定字段值的程序。与 tcpdump 工具相比,tcpdump 读取 pcap 文件的速度大约快了三倍。我的程序真的很简单,但我不知道为什么它很慢。我需要做些什么来提高我的程序的性能?
以下是我的代码。请注意,结果(变量)的类型是 ostringstream。该程序通过重复调用analyze()来读取所有pcap文件来工作。
PcapAnalyzer::PcapAnalyzer(const std::string& filename)
{
PcapAnalyzerfile = fopen("test.pcap", "r");
if (PcapAnalyzerfile == nullptr)
throw std::runtime_error("Failed to read Pcap");
struct PcapAnalyzer_file_header pfh;
if (fread(&pfh, sizeof(pfh), 1, PcapAnalyzerfile) < 1)
throw std::runtime_error("Failed to read Pcap");
if(pfh.linktype != 1)
throw std::runtime_error("No Support");
}
std::string PcapAnalyzer::analyze()
{
int process_len = 0;
int packet_len = 0;
result.str("");
result.clear();
packet_len = PcapAnalyzer_header();
if (packet_len == -1)
return {};
process_len = ethernet();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
packet_len -= process_len;
if (!payload(packet_len))
throw std::runtime_error("failed to analyze");
return result.str();
}
int PcapAnalyzer::PcapAnalyzer_header()
{
struct PcapAnalyzer_pkthdr pp;
char* cap_time;
long sec;
if (fread(&pp, sizeof(pp), 1, PcapAnalyzerfile) < 1)
return -1;
sec = (long)pp.ts.tv_sec;
cap_time = (char*)ctime((const time_t*)&sec);
cap_time[strlen(cap_time) - 1] = '\0';
result << std::dec;
result << pp.len << " ";
result << cap_time << " ";
return pp.caplen;
}
int PcapAnalyzer::ethernet()
{
struct ether_header eh;
int process_len = 0;
if (fread(&eh, sizeof(eh), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(eh);
if(htons(eh.ether_type) != ETHERTYPE_IP)
return process_len;
process_len += ipv4();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
return process_len;
}
int PcapAnalyzer::ipv4()
{
struct ip iph;
int opt = 0;
int process_len = 0;
if (fread(&iph, 20, 1, PcapAnalyzerfile) < 1)
return -1;
result << IP_V(iph.ip_vhl) << " ";
result << IP_HL(iph.ip_vhl) << " ";
result << iph.ip_tos << " ";
result << iph.ip_len << " ";
result << iph.ip_id << " ";
result << iph.ip_off << " ";
result << iph.ip_ttl << " ";
process_len += 20;
opt = IP_HL(iph.ip_vhl) * 4 - sizeof(iph);
if (opt != 0) {
fseek(PcapAnalyzerfile, opt, SEEK_CUR);
process_len += opt;
result << "ip_opt ";
}
if(iph.ip_p != IPPROTO_UDP)
return process_len;
process_len += udp();
if (process_len == -1)
throw std::runtime_error("failed to read transport header");
return process_len;
}
int PcapAnalyzer::udp()
{
struct udphdr udph;
int process_len = 0;
if (fread(&udph, sizeof(udph), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(udph);
result << ntohs(udph.uh_sport) << " ";
result << ntohs(udph.uh_dport) << " ";
result << ntohs(udph.uh_ulen) << " ";
result << ntohs(udph.uh_sum) << " ";
return process_len;
}
bool PcapAnalyzer::payload(int remain_len)
{
if (remain_len == 0)
return true;
char buffer[remain_len];
if (fread(buffer, remain_len, 1, PcapAnalyzerfile) < 1)
return false;
return true;
}
解决方案
推荐阅读
- html - 列表元素底部对齐
- ubuntu - 无法打开 SSL 私钥 [期望:可信证书]
- excel - 如何计算一列中有多少个单元格说“真”,而在其他两列之一中有特定名称
- amazon-gamelift - 如何为 AWS Game Lift 修复此匹配规则集
- c++ - 无法配置 cmake 以使用 cygwin 构建独立的可执行文件
- python - Saleor电子商务平台如何设置VATLAYER_ACCESS_KEY?
- c# - 有没有办法查看并忽略正则表达式中的特定字母?
- javascript - 如何在 Angular 组件中呈现带有上下文的模板?
- javascript - ReferenceError:在初始化之前无法访问“obj”
- javascript - 画布 requestAnimationFrame 的“鬼功能”的可能性