C ++结构声明和用于保存IP +连接的用法

时间:2015-09-04 15:07:08

标签: c++

对所有人来说,美好的一天,我有一个巨大的混乱声明并使用我的结构来举行 [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天的测试,没有任何进展。 非常感谢!

2 个答案:

答案 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)

几个问题。最糟糕的是:

  1. 当您检查的第一个现有IP不等于要添加的IP时,请勿添加新IP。循环遍历它们,只有在现有IP的NONE匹配时才添加。
  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
    

    下一个问题是:

    1. 即使IP与现有IP匹配,您也在递增len。因此,如果你有重复项,那么len将太长,你将循环未初始化的值。
    2. ===============

      仅供参考,这是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从字符串转换为无符号长整数的性能损失。

相关问题