Я пишу приложение, которому требуется возможность отслеживать пропускную способность дискретных профилей сетевого трафика (конечно, с использованием libpcap). Основная идея состоит в том, чтобы накапливать счетчики байтов и пакетов в течение каждого регулярного интервала выборки и использовать его для расчета средней пропускной способности на интервале около 1 секунды.
Каждая точка данных отличается как удаленным адресом, так и удаленным портом. Они будут хранить (очень короткую) историю выборок в кольцевом буфере, состоящем из следующей структуры:
typedef struct {
struct timeval ts_start; // Time at the start of this sample
size_t packets; // packet count during this sample
size_t bytes; // byte count during this sample
} Sample;
Моя первоначальная мысль — сделать что-то с STL и Boost, похожим на следующее:
typedef std::pair<unsigned long /* addr */, unsigned short /* port */> PeerSpec;
typedef boost::circular_buffer<Sample> DataPoint;
std::map<PeerSpec, DataPoint> tracked_peers;
Каждый кольцевой буфер будет иметь небольшое количество элементов, это число определено как 1 + summary_interval / sample_period
, Я думал, что с итоговым интервалом в 1 секунду, тогда будет уместным период выборки 250-1000 миллисекунд (то есть 2-5 выборок истории на точку данных).
Каждая точка данных будет создана и добавлена в tracked_peers
Карта динамически, когда такой трафик наблюдается в захвате. Естественно, счетчики будут обновляться моим обратным вызовом pcap для каждого пакета отдельно.
Это безумие / неразумно / невозможно сделать это таким образом? Я беспокоюсь, что это может быть недостаточно быстро, чтобы не отставать от захвата пакета. Есть ли какая-то семантика копирования, о которой мне нужно знать? Я думаю, что это должно быть уместно, пока я не заставляю циклические буферы копироваться целиком с каждым обновлением. Я спрашиваю, потому что я не уверен, полностью ли я понял все последствия.
Задача ещё не решена.
Других решений пока нет …