The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"split в Си"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 18-Сен-02, 22:35  (MSK)
Привет всем!

Как можно сделать в Си что-то подобное сплиту в perl'е? Задача такова есть файл со статистикой (src dst bytes), надо его обработать и засунуть в базы. При обработке разбить на типы трафика в зависимости от dst.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "RE: split в Си"
Сообщение от sas emailИскать по авторуВ закладки on 18-Сен-02, 23:30  (MSK)
Hi,

classic task for awk:

For example (not tested and just for demo purposes):

------ start below this line ----------
#!/bin/awk -f

BEGIN {
    FS="\t"  # --- Columns separeator
}
{
    gsub( /'/, "''" )  # --- escape single quotes
}
# --- since we need to perform something different based on the
# destination apply different rules below
#
/192\.168\.1\..*/{
    print "insert into table_1 ( dst, src, bytes ) values( '" $1 "', '" $2 "', " $3 ");"  
}
/10\.10\..*/ {
    print "insert into table_2 ( src, bytes ) values( '" $2 "', " $3 ");"
}
------ end ----------------------------

On some systems to get modern ark you have to use nawk.

Awk is very fast and exists on every Unixsystem. Similar program on C will be much more complicated even with regexp libraries.

Thanks
--- Sas

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "RE: split в Си"
Сообщение от XMan emailИскать по авторуВ закладки on 19-Сен-02, 01:47  (MSK)
Ну я бы еще сказал про функцию strsep, но кусок мана гласит:

This function suffers from the same problems as strtok(). In particular, it modifies the original string. Avoid it.

Решать вопрошающему.
А вообще можно пользовать, к примеру, strstr и выдирать по "слову" из строки.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "RE: split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 19-Сен-02, 09:04  (MSK)
Дело в том, что сейчас уже есть обработчик на перле, но файл дневной статистики перевалил за 10 мег. Хотелось бы поднять скорость обработки, а это я понимаю тока на Си выйдет.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "RE: split в Си"
Сообщение от sas emailИскать по авторуВ закладки on 19-Сен-02, 09:34  (MSK)
Hi,

Definetely C will be faster (if written right,but if not it will be slower than perl).

I'm almost positive bottleneck is not perl parsing, but data insertion to the database.

To speedup data import it is better to use some database utility and NOT REGULAR SQL insert statements. For example for Oracle you can use SQL*Loader; for Sybase/MS SQL Server it is bcp etc. It will be much faster to create some kind of the control file and import data to database. In case of Oracle's control file: it is very flexible, so probably you even can skip perl/awk/C format transformation step.

Advantages:
1. This solution will work very fast since this utilities created specifically for this purposes
2. Development time to create control file(s) will be very small.
3. Maintainance will be very simple.

Disadvantages:
1. If your product is working with different dbmss or you are planning to switch between them (i believe it is not a choice) you have to develop different solution for each database type - which leads us to development/maintanance problems.

Conclusion: It is your choice, since we do not know your problem in details.  :)

Thanks
--- sas

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "RE: split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 19-Сен-02, 10:09  (MSK)
>Hi,
>
>Definetely C will be faster (if written right,but if not it will
>be slower than perl).
>
>I'm almost positive bottleneck is not perl parsing, but data insertion to
>the database.
>
>To speedup data import it is better to use some database utility
>and NOT REGULAR SQL insert statements. For example for Oracle you
>can use SQL*Loader; for Sybase/MS SQL Server it is bcp etc.
>It will be much faster to create some kind of the
>control file and import data to database. In case of Oracle's
>control file: it is very flexible, so probably you even can
>skip perl/awk/C format transformation step.
>
>Advantages:
>1. This solution will work very fast since this utilities created specifically
>for this purposes
>2. Development time to create control file(s) will be very small.
>3. Maintainance will be very simple.
>
>Disadvantages:
>1. If your product is working with different dbmss or you are
>planning to switch between them (i believe it is not a
>choice) you have to develop different solution for each database type
>- which leads us to development/maintanance problems.
>
>Conclusion: It is your choice, since we do not know your problem
>in details.  :)

Мне файл статистики надо именно прогнать через обработчик, а не просто запихнуть в базу. Опишу подробней. Файл статистики представляет из себя следующее:

# 10:00
10.0.0.1   10.0.0.2   45    43124
10.0.0.1   200.200.200.200  411    412389
200.200.200.200  10.0.0.1   800    3498989
# 10:10
10.0.0.2   56.56.56.56   123 198918
56.56.56.56   10.0.0.2   500 41235989
# 10:20
и т.д. и т.п.

в базах (MySQL) есть табличка, которая называется
20020919Details (
src int unsigned NOT NULL,
dst int unsigned NOT NULL,
type tinyint unsigned NOT NULL,
bytes bigint unsigned NOT NULL,
time TIME
)

Где type - это тип трафика, то бишь если 0 - внутренний, 1 - пиринг до одного провайдера, 2 - пиринг до другого и т.д.

Как вы наверно заметили айпишники хранятся в виде чисел. Потому и принадлежность айпишника к типу проверяется по методу больше-меньше, а не регулярными выражениями.

В принципе мой перловский обработчик файл длиной 10 мег прогоняет за 2,5 минуты, но хотелось бы повысить скорость обработки.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "RE: split в Си"
Сообщение от Soldier Искать по авторуВ закладки on 19-Сен-02, 11:10  (MSK)
>В принципе мой перловский обработчик файл длиной 10 мег прогоняет за 2,5
>минуты, но хотелось бы повысить скорость обработки.

Возможности перла и awk не сравнить, но у меня mawk 1.3.3 работает в среднем более  чем в 2 раза быстрее чем perl 5.6.1.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "RE: split в Си"
Сообщение от sas emailИскать по авторуВ закладки on 19-Сен-02, 12:08  (MSK)
Hi,

I would try awk first too. Before writing C code.

Because:

1) to write awk program will take 10-20 minutes with debuging
2) maintainance will be also very simple

If speed is not enough, and server is multi-processor. then I will try to split file and then parse it in parallel (number of processes depends on number of CPU).

If this is not enough then C with reading large chunks from file (not lines). Process buffer without strstr, strtok etc.
just using pointers.


Thanks
--- sas

PS unfortunately mysql is not so flexible like sql*loader :(

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "RE: split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 19-Сен-02, 12:33  (MSK)
Спасибо за советы, но уже поздно :-) сделал на Си. Еще вопрос если позволите, мне айпишник в число перевести надо (как inet_aton в sql), как это организовать? В Си inet_aton что-то не то делает...
  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "RE: split в Си"
Сообщение от Soldier Искать по авторуВ закладки on 19-Сен-02, 15:39  (MSK)
>Спасибо за советы, но уже поздно :-) сделал на Си. Еще вопрос
>если позволите, мне айпишник в число перевести надо (как inet_aton в
>sql), как это организовать? В Си inet_aton что-то не то делает...
>

struct in_addr a;
char *host="192.168.11.2";

inet_aton(host,&a);
printf("%i\n",a.s_addr);

У меня a.s_addr состоит из последовательности байтов:
0 -> 192
1 -> 168
2 -> 11
3 -> 2    

То бишь в обратном порядке.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "RE: split в Си"
Сообщение от Александр Искать по авторуВ закладки on 19-Сен-02, 20:00  (MSK)

>struct in_addr a;
>char *host="192.168.11.2";
>
>inet_aton(host,&a);
>printf("%i\n",a.s_addr);
>
>У меня a.s_addr состоит из последовательности байтов:
> 0 -> 192
> 1 -> 168
> 2 -> 11
> 3 -> 2    
>
>То бишь в обратном порядке.
>

inet_aton как и inet_addr и ascii2addr возвращают как и положительные так и отрицательные значения. MySQL принимает тока положительные... что сделать можно?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "RE: split в Си"
Сообщение от XMan emailИскать по авторуВ закладки on 19-Сен-02, 20:19  (MSK)
А преобразовать int в uint (%u вместо %i) ? Обычно помогает :))
  Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "RE: split в Си"
Сообщение от Александр Искать по авторуВ закладки on 19-Сен-02, 20:49  (MSK)
>А преобразовать int в uint (%u вместо %i) ? Обычно помогает :))

Спасибо заработало, ну и последний вопрос :-) функции требуют перевернутый ip. А прямой не сунуть? :-)

Прим.: В Си я еще совсем чайник

  Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "RE: split в Си"
Сообщение от Soldier Искать по авторуВ закладки on 20-Сен-02, 07:36  (MSK)
>Спасибо заработало, ну и последний вопрос :-) функции требуют перевернутый ip. А
>прямой не сунуть? :-)
>
>Прим.: В Си я еще совсем чайник

Функции htonl, ntohl меняют порядок байтов - может поможет.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

16. "RE: split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 24-Сен-02, 11:11  (MSK)
>Функции htonl, ntohl меняют порядок байтов - может поможет.

Спасибо, очень помогло.
Теперь файлик 10 мег формата:
---------------------
# time
src dst packets bytes
---------------------
за 10 сек (!) превращается в файлик формата:
---------------------
srd dst type bytes time
---------------------
Но вот только я начинаю засовывать в базы время обработки этого файла приближается к 2 минутам. Засовываю через API MySQL mysql_query.
Я понимаю, что лучше было бы делать через LOAD INTO и прочее. Но планирую сделать универсальную утилиту, т.к. в будущем планирую снимать статистику каждые 10 мин.
Не можете ли чего посоветовать для оптимизации всего этого дела?

Огромное спасибо всем кто помог и поможет :-)

  Рекомендовать в FAQ | Cообщить модератору | Наверх

17. "RE: split в Си"
Сообщение от gara emailИскать по авторуВ закладки on 24-Сен-02, 12:33  (MSK)
>>Функции htonl, ntohl меняют порядок байтов - может поможет.
>
>Спасибо, очень помогло.
>Теперь файлик 10 мег формата:
>---------------------
># time
>src dst packets bytes
>---------------------
>за 10 сек (!) превращается в файлик формата:
>---------------------
>srd dst type bytes time
>---------------------
>Но вот только я начинаю засовывать в базы время обработки этого файла
>приближается к 2 минутам. Засовываю через API MySQL mysql_query.
>Я понимаю, что лучше было бы делать через LOAD INTO и прочее.
>Но планирую сделать универсальную утилиту, т.к. в будущем планирую снимать статистику
>каждые 10 мин.
>Не можете ли чего посоветовать для оптимизации всего этого дела?
Я бы порекомендовал начать с того чтоб сбрасывать и обрабатывать статистику каждые 10 минут :)) файл статистики будет меньше и как следствие будет быстрее обрабатываться.

Я собираю статистику вообще каждые 3-5 мин. (роутеров ~20)
и все обрабатывается 10-15 сек.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

19. "RE: split в Си"
Сообщение от poige Искать по авторуВ закладки on 05-Окт-02, 13:59  (MSK)
INSERT в MySQL понимает более чем один набор VALUES, таким образом, можно одним INSERT'ом вставить гораздо больше записей. См. док.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "RE: split в Си"
Сообщение от gara emailИскать по авторуВ закладки on 23-Сен-02, 22:46  (MSK)
>Спасибо за советы, но уже поздно :-) сделал на Си. Еще вопрос
>если позволите, мне айпишник в число перевести надо (как inet_aton в
>sql), как это организовать? В Си inet_aton что-то не то делает...
>

Раскажи чем ты в С порезал строку на слова (split)?
Мне скоро тоже придется его юзать.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

15. "RE: split в Си"
Сообщение от Алекс Искать по авторуВ закладки on 24-Сен-02, 11:02  (MSK)
>>Спасибо за советы, но уже поздно :-) сделал на Си. Еще вопрос
>>если позволите, мне айпишник в число перевести надо (как inet_aton в
>>sql), как это организовать? В Си inet_aton что-то не то делает...
>>
>
>Раскажи чем ты в С порезал строку на слова (split)?
>Мне скоро тоже придется его юзать.

fscanf

  Рекомендовать в FAQ | Cообщить модератору | Наверх

18. "RE: split в Си"
Сообщение от vnp emailИскать по авторуВ закладки on 24-Сен-02, 23:02  (MSK)
>Привет всем!
>
>Как можно сделать в Си что-то подобное сплиту в perl'е? Задача такова
>есть файл со статистикой (src dst bytes), надо его обработать и
>засунуть в базы. При обработке разбить на типы трафика в зависимости
>от dst.

Есть семейство функций argz_*. Почему-то man про них умалчивает. Я не
знаю, в какой версии libc они появились, но похоже, что они НЕ есть
GNU extensions.

См. info libc и далее String and Array Utilities --> Argz and Envz
Vectors --> Argz Functions.
И не забудьте #include <argz.h>

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру