2012-12-29 37 views
3

我使用softflowd+nfdump创建NetFlow数据,并将该数据存储在一个2D(串)阵列C++,从基于价值条目

flows = new string *[flows_len]; 
for (int i=0;i<flows_len;i++) 
{ 
    flows[i] = new string[47]; 
} 

我正在写在C + + 2D阵列选择。数组中的每个“行”表示一个流记录,而47是由nfdump显示的netflow数据的不同字段的数量。

我想创建一些基于每个IP的统计数据(例如,每个IP有多少个连接流量),但我无法弄清楚如何获得这些行 - 具有相同IP的流量(数值的srcip存储在流[j] [4],我是新来的c + +)。

在此先感谢!

回答

1

这是一个非常,非常,非常简单的例子

#include <vector> 
#include <string> 
#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

typedef vector<string> StatInfo; // 47 enries 

void print_stat_by_ip(const vector<StatInfo> & infos, const string & ip) { 
    for (int i = 0, count = infos.size(); i < count; i++) { 
     const StatInfo & info = infos[ i ]; 
     if (info[ 4 ] == ip) { 
      copy(info.begin(), info.end(), ostream_iterator<string>(cout, ", ")); 
      cout << endl; 
     } 
    } 
} 

int main() 
{ 
    vector<StatInfo> infos; 

    for (int i = 0; i < 10; i++) { 
     StatInfo info; 
     for (int j = 0; j < 47; j++) { // just filling them "0", "1", "2", ... , "46" 
      char c_str[ 42 ]; 
      sprintf(c_str, "%d", j); 
      info.push_back(c_str); 
     } 
     char c_str[ 42 ]; 
     sprintf(c_str, "%d", rand() % 10); 
     info[ 4 ] = c_str;   // this will be an IP-address 
     infos.push_back(info); 

     copy(info.begin(), info.end(), ostream_iterator<string>(cout, ", ")); 
     cout << endl; 
    } 

    string ip_to_find = "5"; 
    cout << "----------------------------------------" << endl; 
    cout << "stat for " << ip_to_find << endl; 
    cout << "----------------------------------------" << endl; 
    print_stat_by_ip(infos, ip_to_find); 
} 

你可以在这里找到它 http://liveworkspace.org/code/3AAye8

1

老实说,我会考虑你的容器进行反思。下面使用一个标准的lib数组,vector和multimap来完成我认为你在寻找的东西。示例代码只是使用字符串“A”,“B”或“C”以及三个IP地址之一填充表格行。你应该特别注意的部分是multimap的用法,以基于IP地址为你的表建立索引(虽然它可以很容易地改装成对任何任意列执行相同的操作)。

注意:有大量那些比我更精通std lib算法,函数和容器使用情况的人。这只是给你一个关于multimap如何帮助你解决问题的想法。

编辑 OP想查看表中IP地址的计数,此代码已被修改为main()函数的尾部。还更新为不使用C++ 11功能。希望更接近OP可以使用的东西。

#include <iostream> 
#include <iterator> 
#include <algorithm> 
#include <functional> 
#include <map> 
#include <vector> 
#include <string> 
using namespace std; 

// some simple decls for our info, table, and IP mapping. 
typedef std::vector<std::string> FlowInfo; 
typedef std::vector<FlowInfo> FlowTable; 

// a multi-map will likely work for what you want. 
typedef std::multimap<std::string, const FlowInfo* > MapIPToTableIndex; 

// a map of IP string-to-unsigned int for counting occurrences. 
typedef std::map<std::string, unsigned int> MapStringToCount; 

int main(int argc, char *argv[]) 
{ 
    // populate your flow table using whatever method you choose. 
    // I'm just going to push 10 rows of three ip addresses each. 
    FlowTable ft; 
    for (size_t i=0;i<10;++i) 
    { 
     FlowInfo fi(47); // note: always fixed at 47. 

     for (size_t j=0;j<fi.size();++j) 
      fi[j] = "A"; 
     fi[0][0]+=i; 
     fi[4] = "192.168.1.1"; 
     ft.push_back(fi); 

     for (size_t j=0;j<fi.size();++j) 
      fi[j] = "B"; 
     fi[0][0]+=i; 
     fi[4] = "192.168.1.2"; 
     ft.push_back(fi); 

     for (size_t j=0;j<fi.size();++j) 
      fi[j] = "C"; 
     fi[0][0]+=i; 
     fi[4] = "192.168.1.3"; 
     ft.push_back(fi); 
    } 

    // map by IP address into something usefull. 
    MapIPToTableIndex infomap; 
    for (FlowTable::const_iterator it = ft.begin(); it != ft.end(); ++it) 
     infomap.insert(MapIPToTableIndex::value_type((*it)[4], &*it)); 


    // prove the map is setup properly. ask for all items in the map 
    // that honor the 192.168.1.2 address. 
    for (MapIPToTableIndex::const_iterator it = infomap.lower_bound("192.168.1.2"); 
     it != infomap.upper_bound("192.168.1.2"); ++it) 
    { 
     std::copy(it->second->begin(), it->second->end(), 
        ostream_iterator<std::string>(cout, " ")); 
     cout << endl; 
    } 

    // mine the IP occurance rate from the table: 
    MapStringToCount ip_counts; 
    for (FlowTable::const_iterator it= ft.begin(); it!=ft.end(); ++it) 
     ++ip_counts[ (*it)[4] ]; 

    // dump IPs by occurrence counts. 
    for (MapStringToCount::const_iterator it = ip_counts.begin(); 
     it != ip_counts.end(); ++it) 
    { 
     cout << it->first << " : " << it->second << endl; 
    } 

    return 0; 
} 

输出

B B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
C B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
D B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
E B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
F B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
G B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
H B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
I B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
J B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
K B B B 192.168.1.2 B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B 
192.168.1.1 : 10 
192.168.1.2 : 10 
192.168.1.3 : 10 
+0

这似乎真的太好了!但是如果我不知道IP呢?如果我正在监视一个接口,并且我想要计算每个单独的未知IP有多少个连接?另外,因为它更容易与我的2D阵列,我可以做到这一点,没有载体?矢量是需要的地图? – drazenmozart

+0

@drazenmozart矢量是为了表达目的,允许您根据需要添加尽可能多的行。如果你想使用一个固定的数组,它完全取决于你。由于我不熟悉你对“未知”IP地址的定义,所以我只能推测你正在寻找的精确输出。你想要一个IP列表的唯一地址和它们在表中的发生次数?你会惊讶地发现你的桌子很容易。 – WhozCraig

+0

@drazenmozart更新为从'FlowTable'实例中挖掘IP发生率。希望这是你正在寻找的。 – WhozCraig