1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN">
4 <META HTTP-EQUIV=
"CONTENT-TYPE" CONTENT=
"text/html; charset=utf-8">
6 <META NAME=
"GENERATOR" CONTENT=
"OpenOffice.org 2.0 (Linux)">
7 <META NAME=
"CREATED" CONTENT=
"20070612;15584700">
8 <META NAME=
"CHANGED" CONTENT=
"20070623;15471900">
9 <STYLE TYPE=
"text/css">
12 P { margin-bottom: 0.21cm }
16 <BODY LANG=
"ru-RU" DIR=
"LTR">
17 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><FONT SIZE=
4><B>Практическое
18 применение GCLib2
</B></FONT></P>
19 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm">В связи с тем, что
20 означенная библиотека имеет большое
21 количество функций для решения самых
22 различных задач, возникла необходимость
23 в документе, который бы помог
24 сориентироваться и правильно применить
25 всю мощь имеющегося кода. Упор в данном
26 тексте будет делаться не на справочную
27 информацию по функциям, а именно на
28 методы и области применения.
30 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
32 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Базовые классы.
</B></P>
33 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">В
34 библиотеке имеется несколько базовых
35 классов (массив, список, хэш). Эти классы
36 не требуют пояснения. В библиотеке не
37 используется STL или glib по той простой
38 причине, что GCLib
«заточена
» под
39 операционную систему Linux и только Linux.
40 Т.е. вы скорее найдете обертку для нового
41 системного вызова tee, нежели очередную
42 «кроссплатформенную
» функцию
43 «connect
».
</P>
44 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
46 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Обработка
48 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">В
49 GCLib2 большое количество функций направлено
50 именно на обработку данных. При помощи
51 низкоуровневых функций был написан
52 полностью рабочий модуль DNS, код которого
53 составляют всего ~
500 строк. Другие
54 аналогичные библиотеки доступа к DNS, не
55 использующие GCLib2, имеют несколько тысяч
56 строк и требуют много времени чтобы
57 разобраться в их API. Модуль DNS в GCLib
58 предоставляет пару функций, назначение
59 которых не требует даже документирования
60 (dns_A, dns_MX, dns_ip2name).
</P>
61 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
63 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Строковые
65 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">К
66 строковым функциям относятся функции
67 управления памятью и функции поиска и
68 выборки определенных данных из имеющегося
69 блока памяти. Блоки памяти, зачастую
70 это сетевые пакеты, либо обычные файлы.
72 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">К
73 функциям распределения памяти относятся
74 две функции : изменения размера блока
75 и копирования блока (gc_realloc и memdup
77 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">К
78 простым строковым примитивам относятся
79 следующие функции :
</P>
80 <TABLE WIDTH=
606 BORDER=
1 BORDERCOLOR=
"#000000" CELLPADDING=
4 CELLSPACING=
0>
85 <P ALIGN=CENTER
><FONT SIZE=
2>chop
</FONT></P>
88 <P ALIGN=CENTER
><FONT SIZE=
2>Удалить последний
89 символ строки.
</FONT></P>
94 <P ALIGN=CENTER
><FONT SIZE=
2>chomp
</FONT></P>
97 <P ALIGN=CENTER
><FONT SIZE=
2>Удалить конец строки.
</FONT></P>
102 <P ALIGN=CENTER
><FONT SIZE=
2>strchr_r
</FONT></P>
105 <P ALIGN=CENTER
><FONT SIZE=
2>Найти символ (с конца).
</FONT></P>
110 <P ALIGN=CENTER
><FONT SIZE=
2>strchrs
</FONT></P>
113 <P ALIGN=CENTER
><FONT SIZE=
2>Поиск одного из
119 <P ALIGN=CENTER
><FONT SIZE=
2>Dstrstr_r
</FONT></P>
122 <P ALIGN=CENTER
><FONT SIZE=
2>Поиск строки (с конца).
</FONT></P>
127 <P ALIGN=CENTER
><FONT SIZE=
2>Dsyms
</FONT></P>
130 <P ALIGN=CENTER
><FONT SIZE=
2>Посчитать количество
136 <P ALIGN=CENTER
><FONT SIZE=
2>Dmemchr
</FONT></P>
139 <P ALIGN=CENTER
><FONT SIZE=
2>Поиск символа (в блоке).
</FONT></P>
144 <P ALIGN=CENTER
><FONT SIZE=
2>Dstrndup
</FONT></P>
147 <P ALIGN=CENTER
><FONT SIZE=
2>Скопировать несколько
148 символов строки.
</FONT></P>
153 <P ALIGN=CENTER
><FONT SIZE=
2>Dmid_strchr
</FONT></P>
156 <P ALIGN=CENTER
><FONT SIZE=
2>Поиск символа между
157 двумя указателями (началом и концом).
</FONT></P>
162 <P ALIGN=CENTER
><FONT SIZE=
2>Dmid_getstr
</FONT></P>
165 <P ALIGN=CENTER
><FONT SIZE=
2>Взять строку из буфера.
</FONT></P>
170 <P ALIGN=CENTER
><FONT SIZE=
2>Dstrmid
</FONT></P>
173 <P ALIGN=CENTER
><FONT SIZE=
2>Выбрать строку между
174 двух других.
</FONT></P>
179 <P ALIGN=CENTER
><FONT SIZE=
2>Dsplit
</FONT></P>
182 <P ALIGN=CENTER
><FONT SIZE=
2>Разбить строку.
</FONT></P>
187 <P ALIGN=CENTER
><FONT SIZE=
2>Drand_str
</FONT></P>
190 <P ALIGN=CENTER
><FONT SIZE=
2>Случайная строка.
</FONT></P>
195 <P ALIGN=CENTER
><FONT SIZE=
2>int2str
</FONT></P>
198 <P ALIGN=CENTER
><FONT SIZE=
2>Число в новую строку.
</FONT></P>
203 <P ALIGN=CENTER
><FONT SIZE=
2>stail
</FONT></P>
206 <P ALIGN=CENTER
><FONT SIZE=
2>Указатель на последний
212 <P ALIGN=CENTER
><FONT SIZE=
2>strmov
</FONT></P>
215 <P ALIGN=CENTER
><FONT SIZE=
2>Копировать строку.
</FONT></P>
220 <P ALIGN=CENTER
><FONT SIZE=
2>strip
</FONT></P>
223 <P ALIGN=CENTER
><FONT SIZE=
2>Удалить начальные
224 пробельные символы.
</FONT></P>
229 <P ALIGN=CENTER
><FONT SIZE=
2>strip2
</FONT></P>
232 <P ALIGN=CENTER
><FONT SIZE=
2>Удалить конечные
233 пробельные символы.
</FONT></P>
237 <TD WIDTH=
136 HEIGHT=
41>
238 <P ALIGN=CENTER
><FONT SIZE=
2>Dmemmem
</FONT></P>
241 <P ALIGN=CENTER
><FONT SIZE=
2>Аналог memmem (
3)
</FONT></P>
246 <P ALIGN=CENTER
><FONT SIZE=
2>Dmid_memmem
</FONT></P>
249 <P ALIGN=CENTER
><FONT SIZE=
2>Найти блок между
250 указателями.
</FONT></P>
255 <P ALIGN=CENTER
><FONT SIZE=
2>Dsprintf
</FONT></P>
258 <P ALIGN=CENTER
><FONT SIZE=
2>Отформатированная
259 строка (не более
512 символов).
</FONT></P>
263 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><BR>
265 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Список.
</B></P>
266 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Для
267 создания разного рода списков существует
268 класс EList. Элементы добавляются функциями
269 add_head (добавление в начало) и add_tail
270 (добавление в конец). Навигация по
271 элементам – first (перемещение к первому
272 элементу), last (перемещение к последнему
273 элементу), next (следующий элемент), prev
274 (предыдущий элемент). Выход за границы
275 списка определяется функцией eol ()
276 (возвращает true, если курсор вышел за
278 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><BR>
280 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>«Пакетные
»
282 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">К
283 пакетным функциям относится код,
284 оперирующий с блоками данных, полученных
285 сетевым путем. Конечно, данный функционал
286 можно применять и на другие данные.
</P>
287 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
289 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Пакетные
291 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">К
292 пакетным примитивам относятся функции
294 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">pkt_W8,
295 pkt_W16, pkt_W32, pkt_WS, pkt_WSZ, pkt_WD
297 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">каждая
298 из которых записывает определенные
299 данные : байт, два байта, четыре байта,
300 строку, строку с нулем, блок данных.
</P>
301 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Так
302 же функции чтения из пакета : pkt_R8, pkt_R16,
304 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">При
305 использовании пакетных примитивов
306 обязателен контроль выхода за границу
307 буфера. Эти функции предназначены для
308 програм на Си. Для программ на Си++
309 рекомендую использовать DPBuf.
</P>
310 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
312 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Устойчивый
314 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Для
315 «защищенного
» доступа к любым
316 данным, без риска выхода за границу
317 пакета, существует класс -
«устойчивый
318 буфер
» DPBuf. Класс позволяет читать
319 данные и перемещаться в любую позицию
320 пакета. Если в какой-то момент произошел
321 выход за границу, переменная
«ok
»
322 буфера установится в false. При этом чтения
323 данных не произойдет. Реализованы
324 функции чтения (r*), смещения (s*), записи
325 (w*). Так же можно получить
327 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">поток
328 FILE * (командой file ()).
</P>
329 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
331 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Файловая
333 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Системные
334 вызовы контролирующие файловую систему
335 на столько базовые, что работа с ними
336 представляется делом очень нудным и не
337 рациональным. Неумение пользоваться
338 данными системными вызовами приводит
339 либо к отказу от разработки под
340 операционную систему Linux, либо к переходу
341 на языки
«более высокого уровня
».
342 На практике же достаточно написать пару
343 функций-оберток, которые будут иметь
344 удобный интерфейс пользователя и
345 сохранят всю мощь системного
346 программирования. В библиотеке GCLib2 я и
347 реализовал все эти функции.
349 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Функции
350 быстрого доступа к данным из файла :
</P>
351 <TABLE WIDTH=
588 BORDER=
1 BORDERCOLOR=
"#000000" CELLPADDING=
4 CELLSPACING=
0>
356 <P ALIGN=LEFT
>Dfnwrite
</P>
359 <P ALIGN=LEFT
>Записать непосредственно в
365 <P ALIGN=LEFT
>Dfnread
</P>
368 <P ALIGN=LEFT
>Прочитать непосредственно из
374 <P ALIGN=LEFT
>DFILE
</P>
377 <P ALIGN=LEFT
>Прочитать весь файл.
</P>
382 <P ALIGN=LEFT
>DFDMAP
</P>
385 <P ALIGN=LEFT
>mmap'нуть дескриптор файла (все
391 <P ALIGN=LEFT
>DFMAP
</P>
394 <P ALIGN=LEFT
>mmap'нуть файл.
</P>
399 <P ALIGN=LEFT
>Dread_to_eof
</P>
402 <P ALIGN=LEFT
>Прочитать все из дескриптора.
</P>
407 <P ALIGN=LEFT
>Dtmpfd
</P>
410 <P ALIGN=LEFT
>Вернуть дескриптор временного
416 <P ALIGN=LEFT
>logToFile
</P>
419 <P ALIGN=LEFT
>Записать строчку в конец файл.
</P>
424 <P ALIGN=LEFT
>DSTR
</P>
427 <P ALIGN=LEFT
>Прочитать строчку из файла.
</P>
432 <P ALIGN=LEFT
>copyFile
</P>
435 <P ALIGN=LEFT
>Скопировать файл.
</P>
439 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Функции
440 контроля файловой системы :
</P>
441 <TABLE WIDTH=
586 BORDER=
1 BORDERCOLOR=
"#000000" CELLPADDING=
4 CELLSPACING=
0>
446 <P ALIGN=LEFT
>Dselect
</P>
449 <P ALIGN=LEFT
>Ожидать данные.
</P>
454 <P ALIGN=LEFT
>DSTAT
</P>
457 <P ALIGN=LEFT
>stat (
2)
</P>
462 <P ALIGN=LEFT
>DLSTAT
</P>
465 <P ALIGN=LEFT
>lstat (
2)
</P>
470 <P ALIGN=LEFT
>DIONREAD
</P>
473 <P ALIGN=LEFT
>Количество байт, доступных
479 <P ALIGN=LEFT
>fsize
</P>
482 <P ALIGN=LEFT
>Размер файла (по имени).
</P>
487 <P ALIGN=LEFT
>fdsize
</P>
490 <P ALIGN=LEFT
>Размер файла (по дескриптору).
</P>
495 <P ALIGN=LEFT
>move_stream
499 <P ALIGN=LEFT
>Переместить все данные из
500 одного дескриптора в другой.
</P>
505 <P ALIGN=LEFT
>Dnonblock
</P>
508 <P ALIGN=LEFT
>Включить неблокируемый режим.
</P>
513 <P ALIGN=LEFT
>close_pipe
</P>
516 <P ALIGN=LEFT
>Закрыть трубу.
</P>
521 <P ALIGN=LEFT
>fdclose
</P>
524 <P ALIGN=LEFT
>Закрыть (открытый) дескриптор.
</P>
529 <P ALIGN=LEFT
>fext
</P>
532 <P ALIGN=LEFT
>Получить расширение файла.
</P>
537 <P ALIGN=LEFT
>Dfiles
</P>
540 <P ALIGN=LEFT
>Получить список файлов в
545 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
547 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Сетевой модуль.
</B></P>
548 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">При
549 системном программировании вы бы
550 использовали функии bind,connect,send,recv и иже
551 с ними. На самом деле вам необходимо
552 две-три функции, объединяющие эти
553 системные вызовы (
«сетевых примитивов
»).
554 Здесь вы их и найдете. Все функции
555 работают (на данный момент) только с
556 IPv4. Все порты – не сетевой формат. Все
557 адреса – строка вида
«xxx.xxx.xxx.xxx
».
558 Т.е. sockaddr_in нигде не используется.
</P>
559 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
561 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Сетевые
563 <TABLE WIDTH=
586 BORDER=
1 BORDERCOLOR=
"#000000" CELLPADDING=
4 CELLSPACING=
0>
568 <P ALIGN=LEFT
>dSocket
</P>
571 <P ALIGN=LEFT
>Новый сокет.
</P>
576 <P ALIGN=LEFT
>dUdpSocket
</P>
579 <P ALIGN=LEFT
>Новый UDP сокет.
</P>
584 <P ALIGN=LEFT
>sendToPath
</P>
587 <P ALIGN=LEFT
>послать UDP в именнованый канал.
593 <P ALIGN=LEFT
>sendToSocket
</P>
596 <P ALIGN=LEFT
>послать UDP используя существующий
602 <P ALIGN=LEFT
>sendTo
</P>
605 <P ALIGN=LEFT
>Послать UDP непосредственно
611 <P ALIGN=LEFT
>dBind
</P>
614 <P ALIGN=LEFT
>bind'нуть сокет.
</P>
619 <P ALIGN=LEFT
>dConnect
</P>
622 <P ALIGN=LEFT
>Подключить сокет.
</P>
627 <P ALIGN=LEFT
>getHostByName
</P>
630 <P ALIGN=LEFT
>Адрес по имени.
</P>
635 <P ALIGN=LEFT
>getNameByHost
</P>
638 <P ALIGN=LEFT
>Имя по адресу.
</P>
643 <P ALIGN=LEFT
>recvFrom
</P>
646 <P ALIGN=LEFT
>Получить UDP.
</P>
651 <P ALIGN=LEFT
>setBroadcast
</P>
654 <P ALIGN=LEFT
>Включить BROADCAST на сокет.
</P>
659 <P ALIGN=LEFT
>pollScan
</P>
662 <P ALIGN=LEFT
>Найти
"готовый
" pollfd.
</P>
667 <P ALIGN=LEFT
>Dpoll_add
</P>
670 <P ALIGN=LEFT
>Добавить дескриптор в пул. пул
671 – EArray с элементами pollfd *
</P>
676 <P ALIGN=LEFT
>Dpoll_coallesce
</P>
679 <P ALIGN=LEFT
>Собрать пул для poll (
2).
</P>
683 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
685 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Сетевые классы.
</B></P>
686 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Для
687 доступа к сети так же есть два класса –
688 DConnection и DPoll. Первый обобщает всю
689 информацию, которая может быть необходима
690 при обработке соединения. Для инициализации
691 соединения – выполняется
«init
», и
692 далее
«bind
» или
«connect
». Для
693 UDP необходимо использовать initUdp и
694 connectUdp. После
«подключения
» вы
695 можете использовать sendTo, передавая в
696 качестве аргумента только пакет и его
698 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-weight: medium">Использование
699 DPoll тоже не должно быть проблемой.
700 Выполняется добавление нужных соединений
701 или дескрипторов, затем poll_build и в цикле
702 poll_rebuild. Поиск
«готовых
» выполняется
703 при помощи scan или непосредственно через
705 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
707 <P ALIGN=CENTER
STYLE=
"margin-bottom: 0cm"><B>Контроль
708 дочерних процессов.
</B></P>
709 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-style: normal; font-weight: medium">
710 <FONT SIZE=
3>В Линуксе при создании приложений,
711 рассчитанных на многопроцессорные
712 системы, в основном используют
«треды
»
713 (threads'), и, соответственно стандартную
714 библиотеку pthread. Использование данной
715 библиотеки ведет к увеличению кода,
716 зачастую на порядок (по сравнению с
717 однопроцессорной версией программы).
718 Поэтому многопроцессорное ПО берутся
719 писать только такие монстры как apache. На
720 деле же код написанный для pthread вообще
721 не несет смысловую нагрузку. Если не
722 брать в расчет не хилое API pthread, а докопаться
723 до сути, мы увидим только один системный
724 вызов – fork. Т.е. нам нужна только
«вилка
»
725 ! Треды считаются
«лучше
», потому
726 что у дочернего потока и родительского
727 процесса одно адресное пространство и
728 потоки быстрее создаются. Что же видим
729 на практике ? Одно адресное пространство
730 заставляет
«бояться
» практически
731 любых функций. На доступ к своим же
732 данным надо ставить заглушки/замки в
733 виде семафоров. Польза же от быстрого
734 создания потока стремиться к нулю, ибо
735 все необходимые процессы могут быть
736 созданы один раз, при запуске программы.
</FONT></P>
737 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
739 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-style: normal; font-weight: medium">
740 <FONT SIZE=
3>Да, конечно, применение тредов,
741 в некоторых случаях, вполне обосновано.
742 С другой стороны существует огромное
743 множество программ, которые не поддерживают
744 многопроцессорные системы
«в
745 принципе
». А ведь для того чтобы
746 программа начала работать на любом
747 количестве процессоров, необходимо и
748 достаточно только
«вилки
» ! Плюс,
749 конечно, грамотная структура программы.
752 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
754 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm; font-style: normal; font-weight: medium">
755 <FONT SIZE=
3>В GCLib существуют средства более
756 высокого уровня, нежели простой fork. К
757 этим средствам относится единственный
758 класс Djobs. Данный класс может создавать
759 дочерние процессы, ведя их учет. Поэтому
760 чтобы дождаться завершения всех дочерних
761 процессов достаточно вызвать функцию
763 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
765 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
767 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>
769 <P ALIGN=LEFT
STYLE=
"margin-bottom: 0cm"><BR>