在 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;
我进行了一些更改以最适合您的目的,并且没有检查它是否可以编译,如果您无法弄清楚我可以为您提供帮助。
这基本上就是你使用它的方式:你有一个名为 的 IP 列表,my_ip_map
默认情况下它是空的。
您可以在其中创建元素或使用以下方法更新它:
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;
}
出于性能原因,其结构为堆栈(最后添加的元素首先出现)。