3

私はsoftflowd+nfdumpネットフローデータを作成し、このデータを2次元(文字列)配列に保存するために使用しています

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

私はc++で書いています。配列内の各「行」はフロー レコードを表し、47 は nfdump によって表示されるネットフロー データの異なるフィールドの数です。

IP ごとにいくつかの統計を作成したい (たとえば、IP ごとにいくつの接続フローがあるか) が、同じ IP (srcip の値が保存されている) でそれらの行フローを取得する方法がわかりませんフロー[j] [4]で、私はc ++が初めてです)。

前もって感謝します!

4

2 に答える 2

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

于 2012-12-29T09:50:47.513 に答える
1

正直なところ、コンテナの再考を検討します。以下では、標準の lib 配列、ベクター、およびマルチマップを使用して、探しているものを実現しています。サンプル コードでは、3 つの IP アドレスのうちの 1 つと共に、文字列 "A"、"B"、または "C" をテーブルの行に入力するだけです。特別な注意を払うべき部分は、マルチマップを使用して IP アドレスに基づいてテーブルにインデックスを付けることです (ただし、任意の列に対して同じことを行うように簡単に改造できます)。

注: std lib アルゴリズム、関数、およびコンテナーの使用に私よりも精通している人はたくさんいます。

EDIT 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
于 2012-12-29T10:40:35.013 に答える