Как я могу улучшить производительность чтения файлов?

Я создал программу на С ++, которая читает и анализирует файлы pcap с помощью функции fread.

Это программа, которая читает глобальный заголовок файла pcap, читает заголовок pcap и извлекает определенное значение поля, указав структуру каждого заголовка протокола. По сравнению с инструментом tcpdump tcpdump читает файл pcap примерно в три раза быстрее. Моя программа действительно простая, но я не знаю, почему она медленная. Что мне нужно сделать, чтобы улучшить производительность моей программы?

Ниже мой код. Обратите внимание, что тип результата (Variable) — ostringstream. и Программа работает, вызывая analysis (), чтобы прочитать все файлы 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;
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]