对所有人来说,美好的一天,我有一个巨大的混乱声明并使用我的结构来举行 [IP] - [连接] 记录。 我正在尝试插入连接到结构中的IP地址,并且他的连接号#,例如,如果 IP 123.123.12 连接2(两)次,那么更新 IP(123.123.12)的结构中的 [连接] 编号。
我有以下代码,应该有效:
// the struct
typedef struct {
int id; // is this usefull anyway ?
char *ip;
int connNumbers;
}test_sock;
// init struct
test_sock holder[5000];
int len = 0;
// the function
void AddtoStruct(char *ip)
{
if (len == 0) //if empty, insert.
{
len++;
holder->id = len;
holder->ip = ip;
holder->connNumbers = 1; //1 conexiune
return;
}
for (int i = 0; i<len; i++)
{
if (test_sock->id != 0) //check if its the same id !?
{
//Exista deja in structura , doar increase connNumbers;
if (strcmp(ip, holder->ip) == 0)
{
holder++;
holder->connNumbers++;
holder->id = antiddos_len;
holder->ip = ip;
return; // should return or not ?!
}
else{ //new IP, insert into struct.
len++; // COUNT AGAIN ?
holder->id = len;
holder->ip = ip;
holder->connNumbers = 1; // 1 connection
return; // should return or not ?!
}
}
}
}
好吧它应该是什么: 检查新传入的 IP ,如果结构中 ALLREADY ,则增加该IP的连接数 如果新的传入 IP 在结构中不,请插入它,如果他再次连接,当然会增加连接数。
我在下面编译了一个最小的例子,你可以在Windows机器上使用Visual Studio(我使用2013)运行时没有问题。
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;
// the struct
typedef struct {
int id; // is this usefull anyway ?
char *ip;
int connNumbers;
}test_sock;
// init struct
test_sock holder[5000];
int len = 0;
// the function
void AddtoStruct(char *ip)
{
if (len == 0) //if the struct is empty, insert.
{
len++;
holder->id = len;
holder->ip = ip;
holder->connNumbers = 1; //1 conexiune
cout << "ADDED NEW IP: " << holder->ip << " Connections: " << holder->connNumbers << endl;
cout << "-----------------------------------------------------------" << endl;
return;
}
for (int i = 0; i <= len; i++)
{
if (holder->id != 0) //verificam ca sa nu fie ACELASI ID
{
//Exista deja in structura , doar increase connNumbers;
if (strcmp(ip, holder->ip) == 0)
{
len++;
holder->connNumbers++;
holder->id = len;
holder->ip = ip;
cout << "NEW CONNECTION FROM IP: " << holder->ip << " Connections: " << holder->connNumbers << endl;
cout << "-----------------------------------------------------------" << endl;
}
else{ //new IP, insert into struct.
len++; // COUNT AGAIN ?
holder->id = len;
holder->ip = ip;
holder->connNumbers = 1; // 1 connection
cout << "CONNECTION FROM NEW IP: " << holder->ip << " Connections: " << holder->connNumbers << endl;
cout << "-----------------------------------------------------------" << endl;
return; // should return or not ?!
}
}
}
}
// use the function
int main() {
char *ip = "127.0.0.1";
char *ip2 = "127.0.0.3";
AddtoStruct(ip);
Sleep(5); // wait for new IP
AddtoStruct(ip2);
Sleep(5); // wait for SAME IP
AddtoStruct(ip);
system("pause");
}
正如您所看到的,如果您运行代码,它不能正常工作,它会为每个新IP计算相同数量的连接... 所以,请给我建议,或修复,或任何东西,因为我真的需要这个,它是3天的测试,没有任何进展。 非常感谢!
答案 0 :(得分:3)
试试这个。此代码使用std :: vector。
#include <iostream>
#include <Windows.h>
#include <vector>
using namespace std;
struct test_sock
{
test_sock()
{
memset(IP, 0, sizeof(IP));
con_count = 0;
}
char IP[15];
int con_count;
};
vector<test_sock>data_holder;
void AddtoStruct(char *ip)
{
if (ip == NULL)
{
cout << "Error: ip == NULL!" << endl;
return;
}
else
{
// Try to verify if IP is already in data_holder
vector<test_sock>::iterator itr = data_holder.begin();
for (; itr != data_holder.end(); ++itr)
{
if (strcmp((*itr).IP, ip) == 0)
{
(*itr).con_count++;
break;
}
}
// If not, create new instance and save IP
if (itr == data_holder.end())
{
data_holder.resize(data_holder.size() + 1);
memcpy(data_holder[data_holder.size() - 1].IP, ip, strlen(ip));
data_holder[data_holder.size() - 1].con_count = 1;
// This handles new IPs
cout << "[DATA HOLDER] ip: " << data_holder[data_holder.size() - 1].IP << " Connections: " << data_holder[data_holder.size() - 1].con_count << endl;
}
// Else increase con_count value for existing IP
else
{
// This handles exists IPs
cout << "[DATA HOLDER] ip: " << (*itr).IP << " Connections: " << (*itr).con_count << endl;
}
}
}
int main()
{
char *ip = "127.0.0.1";
char *ip2 = "127.0.0.3";
AddtoStruct(ip);
AddtoStruct(ip2);
AddtoStruct(ip);
AddtoStruct(ip2);
AddtoStruct(ip2);
AddtoStruct(ip2);
getchar();
}
答案 1 :(得分:2)
几个问题。最糟糕的是:
的伪代码:
unset found flag
loop over existing IPs
if match
increment count
set found flag
break out of loop
end loop
if found flag NOT set
add new IP
下一个问题是:
===============
仅供参考,这是STL的做法。它使用std :: map,它不仅显着减少了所需的代码量,而且还具有优化的find()函数,当添加了许多很多时,它将大大减少搜索先前IP所花费的时间。
#include <iostream>
#include <map>
using namespace std;
map < string, int > IPCollection;
void AddToIPCollection( char* ip )
{
map < string, int >::iterator it = IPCollection.find( string( ip ));
if( it == IPCollection.end() )
{
// new IP
IPCollection.insert( pair< string, int >( ip, 1 ) );
cout << "CONNECTION FROM NEW IP: " << ip << " Connections: " << 1 << endl;
}
else
{
// increment connection count of existing IP
it->second += 1;
cout << "NEW CONNECTION FROM IP: " << ip << " Connections: " << it->second << endl;
}
}
int main()
{
char *ip = "127.0.0.1";
char *ip2 = "127.0.0.3";
AddToIPCollection(ip);
AddToIPCollection(ip2);
AddToIPCollection(ip);
return 0;
}
此表现应足以支持多达一百万个唯一IP。如果你需要更多,你应该能够通过在存储它们之前将IP转换为无符号长整数来挤出一些额外的性能(包括时间和内存)。
map < unsigned long, int > IPCollection;
您需要仔细测试,以发现通过优化查找和插入数字而不是字符串来优化将IP从字符串转换为无符号长整数的性能损失。