先来看一段代码,功能是实现IP的统计,如果一个IP出现三次就触发相应的处理,但是每个Ip统计始终为1,具体如下,
EdgeMonitor.h
#include <unistd.h>
#include <stdarg.h>
#include <iostream>
#include <string>
#include <map>
using namespace std;
#define EDGE_DEBUG
#ifdef EDGE_DEBUG
#define DBG_LOG(...) do {fprintf(stderr, "File: %s Line %d - ", __FILE__, __LINE__);\
fprintf(stderr, __VA_ARGS__);\
fprintf(stderr, "\n");}\
while(0)
#else
#define DBG_LOG(...)
#endif
static const int g_edge_connect_nr = 3;
enum {MAIL_WARN_TYPE_EDGE_SMTP = 32};
class CEdgeRecord
{
public:
CEdgeRecord();
~CEdgeRecord();
int checkNr(string &clientIP);
private:
int m_nr;
};
class CEdgeMonitor
{
public:
CEdgeMonitor();
~CEdgeMonitor();
int addOrUpdateRecord(string &clientIP, CEdgeRecord &r_outdata);
int process(string &clientIP);
private:
map<string, CEdgeRecord*> m_all_ipmap;//维护所有ip的当前以及历史ip信息
};
#endif
EdgeMonitor.cpp
#include "EdgeMonitor.h"
CEdgeRecord::CEdgeRecord ()
{
m_nr = 0;
}
CEdgeRecord::~CEdgeRecord ()
{}
int CEdgeRecord::checkNr(string &clientIP)
{
int warntype = 0;
m_nr++;
if(m_nr >= g_edge_connect_nr)
{
warntype = MAIL_WARN_TYPE_EDGE_SMTP;
m_nr = 0;
}
DBG_LOG("MAIL_EDGE_WARN: clientIP(%s), nr(%d), NR(%d)",
clientIP.c_str(), m_nr, g_edge_connect_nr);
return warntype;
}
CEdgeMonitor::CEdgeMonitor()
{
}
CEdgeMonitor::~CEdgeMonitor()
{
map<string, CEdgeRecord*>::iterator iter_rbtree_map;
iter_rbtree_map = m_all_ipmap.begin();
while (iter_rbtree_map != m_all_ipmap.end())
{
if (NULL != iter_rbtree_map->second)
{
delete iter_rbtree_map->second;
iter_rbtree_map->second = NULL;
}
iter_rbtree_map++;
}
m_all_ipmap.clear();
}
int CEdgeMonitor::addOrUpdateRecord(string &clientIP, CEdgeRecord &r_outdata)
{
CEdgeRecord *p_record = NULL;
if (m_all_ipmap.count(clientIP) < 1)
{
p_record = new CEdgeRecord();
if (NULL == p_record)
{
DBG_LOG("Failed to new CEdgeRecord");
return -1;
}
m_all_ipmap.insert(make_pair(clientIP, p_record));
}
else
{
p_record = m_all_ipmap[clientIP];
}
r_outdata = *p_record;
return 0;
}
int CEdgeMonitor::process(string &clientIP)
{
CEdgeRecord r_outdata;
int warnType = 0;
//添加到历史记录中
if(0 != addOrUpdateRecord(clientIP, r_outdata))
{
return -1;
}
//检查告警
warnType =r_outdata.checkNr(clientIP);
DBG_LOG("warnType (%d)", warnType);
return 0;
}
int main()
{
string clientip("172.22.1.16");
string clientip2("172.22.1.17");
string clientip3("172.22.1.18");
CEdgeMonitor *mm = new CEdgeMonitor();
mm->process(clientip);
mm->process(clientip);
mm->process(clientip);
mm->process(clientip);
mm->process(clientip2);
mm->process(clientip2);
mm->process(clientip2);
mm->process(clientip2);
delete mm;
return 0;
}
# g++ EdgeMonitor.cpp
#./a.out
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17),nr(1),NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
原因在于
r_outdata = *p_record;
解决办法:
int CEdgeMonitor::addOrUpdateRecord(string &clientIP, CEdgeRecord **pp_outdata)
{
。。。。。
*pp_outdata = p_record;
}
int CEdgeMonitor::process(string &clientIP)
{
CEdgeRecord *p_outdata = NULL;
int ret = addOrUpdateRecord(clientIP, &p_outdata)
if(0 != ret || NULL ==p_outdata )
{
return -1;
}
warnType = p_outdata->checkNr(clientIP);
。。。。
}
# g++ EdgeMonitor.cpp
#./a.out
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(2), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(0), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (32)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.16), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(2), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(0), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (32)
File: EdgeMonitor.cpp Line 23 - MAIL_EDGE_WARN: clientIP(172.22.1.17), nr(1), NR(3)
File: EdgeMonitor.cpp Line 88 - warnType (0)