簡體   English   中英

如何按C中的IP地址對傳輸進行分組以計算傳輸速率?

[英]How to group transfers by IP address in C to calculate transfer rates?

我是C的初學者,我遇到了一個有趣的問題。

我正在捕獲端口80上的所有傳出數據包,我想計算每個IP的傳輸速度。 但問題是我不知道如何對這些IP地址進行分組,在PHP中我可以通過IP創建數組和索引條目並搜索數組,如果IP索引已經存在,則傳輸更新值字節,然后將其除以經過的秒數,我有B / s的傳輸速度。 但在CI中無法做到這一點。

建議我如何實現我的問題,因為現在我只能計算整體傳輸速度。

  t2 = time(0);
  time_elapsed = (int) (t2-t1);
  if(time_elapsed > 0) {
    bytes += Size;
    //packets size SUM from all IP addresses, which is incorrect

    printf("IP: %s | Size: %d\n\n", inet_ntoa(dest.sin_addr), Size);
  }

產量

IP: 77.236.192.100 | Size: 4434

IP: 89.176.81.106 | Size: 43854

IP: 89.176.81.106 | Size: 20494

IP: 89.176.81.106 | Size: 24874

IP: 77.236.192.100 | Size: 7354

IP: 89.176.81.106 | Size: 39474

IP: 89.176.81.106 | Size: 16114

在C中,您可以使用帶有指針的鏈式節點,也稱為隊列,列表或堆棧(取決於其結構如何)。 我有一個可能適合您的代碼:

struct _ip_map_node {
    struct _ip_map_node* next;
    unsigned long ip;
    unsigned long transfered;
    unsigned long time;
};
typedef struct _ip_map_node ip_map_node;

ip_map_node* update_or_create_ip_map_node(ip_map_node** queue, unsigned long ip, unsigned long transfered) {
    ip_map_node* node = *queue;
    while (node) {
        if (node->ip == ip) {
            node->transfered += transfered;
            return node;
        }
        node = node->next;
    }
    node = malloc(sizeof(ip_map_node));
    node->next = *queue;
    *queue = node;

    node->ip = ip;
    node->transfered = transfered;
    node->time = time(NULL);

    return node;
}

void remove_ip_map_node(ip_map_node** queue, unsigned long ip) {
    ip_map_node* last = NULL;
    ip_map_node* curr = *queue;
    while (curr) {
        if (curr->ip == ip) {
            if (last)
                last->next = curr->next;
            else
                *queue = curr->next;

            free(curr);
            break;
        }
        last = curr;
        curr = curr->next;
    }
}

ip_map_node* my_ip_map = NULL;

我做了一些更改以最適合您的目的,並沒有檢查它是否編譯,如果您無法搞清楚我可以幫助您。

這基本上就是你如何使用它:你有一個名為my_ip_map的IP列表,默認為空。

您可以在其中創建元素或使用以下命令更新它:

ip_map_node* node = update_or_create_ip_map_node(&my_ip_map, dest.sin_addr.s_addr, data_size);

其中data_size是此時轉移到該IP的字節數。 它將自動匯總為先前發送到同一IP的金額。

然后該node具有以下屬性:

node->ip; // The IP in numeric format, use inet_ntoa() to transform it
node->transfered; // The amount that was transfered to that IP so far
node->time; // the time(NULL) when the first packet was sent to this IP

您現在可以使用node->transfered / (time(NULL) - node->time)獲取傳輸速度 - 請注意,因為除零會崩潰。

如果要每隔幾秒重置一次此節點,您可以使用:

node->transfered = 0;
node->time = time(NULL);

或者刪除它:

remove_ip_map_node(&my_ip_map, dest.sin_addr);

並且可以在列表中運行所有IP,例如:

ip_map_node* node = my_ip_map;
while(node) {
    printf("%s, %d\n", inet_ntoa(*(struct in_addr *)&node->ip), node->transfered);
    node = node->next;
}

出於性能原因,它的結構為堆棧(最后添加的元素首先出現)。

C ++中 ,如果需要一個關聯容器(可以通過包含IP的字符串訪問),可以使用map< string, float >類型的映射容器 (當然,如果使用字符串存儲IP)

然后你可以通過執行你的yourMapName[IPaddress]來訪問元素。

如果你需要在C中做,你需要做一個包含IP地址的struct (如果它是純C,你可能會使用char*unsigned int 。那么你需要做一個這樣的結構數組和一個函數,它在數組中搜索具有給定char*的結構並添加到int中,或者在數組中添加一個新條目。

如果您需要使結構數組靈活(因為您不知道將連接多少IP),您將需要學習如何使用mallocfree C函數。

所以,如果你沒有堅持使用純C - 那么在C ++中這樣做會更直接。 只是一個提示,這是你的選擇。

不要自己實現,使用C中可用的大量庫之一。使用glib的示例:

#include <glib.h>
#include <stdio.h>

unsigned lookup(GHashTable *dict, const char *key)
{
    return GPOINTER_TO_UINT(g_hash_table_lookup(dict, key));
}

void accumulate(GHashTable *dict, char *key, unsigned increment)
{
    unsigned value;

    value = lookup(dict, key);
    g_hash_table_insert(dict, key, GUINT_TO_POINTER(value + increment));
}

int main(void)
{
    GHashTable *ip;

    ip = g_hash_table_new(g_str_hash, g_str_equal);
    accumulate(ip, "10.1.1.1", 0);
    accumulate(ip, "10.10.10.10", 2);
    accumulate(ip, "10.1.1.1", 2);
    accumulate(ip, "10.1.1.1", 3);
    accumulate(ip, "10.2.2.2", 10);

    printf("%u\n", lookup(ip, "10.1.1.1"));
    printf("%u\n", lookup(ip, "10.10.10.10"));
    printf("%u\n", lookup(ip, "10.2.2.2"));

    g_hash_table_unref(ip);

    return 0;
}

輸出:

$ ./hash 
5
2
10

https://developer.gnome.org/glib/2.38/glib-Hash-Tables.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM