Летняя практика (Unix-programming)

Oct 04, 2005 23:58

Таки наконец написал, сдал и защитил летнюю практику. Темой я себе выбрал написание клиент-серверной системы с unix-сервером. Чтобы, значится, научиться программировать под юниксы (ну в общем-то так и есть...) и все такое. Ну вот стало быть, летом я сначала колотил балду, потом три недели сочинял протокол ("может сегодня перевыполнить план и написать 2 абзаца?"), потом за 6 дней настрочил клиента на Delphi, без тестирования, ибо нечем. В процессе оценил удобства редактора Delphi, вроде autocompletion. Потом неспеша принялся за сервер.. опаньки, а тут в Томск пора ехать.
В Томске к этому делу изъявил желание подключиться сосед-линуксоид. Положили под CVS и поехали. Впрочем, писал он совершеннейшую чушь (в commands.c), пришлось переделывать.
В процессе, как водится, выловили огромное количество багов. Начиная от смешных, когда & вместо && в if вываливал сервер в корку сразу при старте, продолжая "невозможными", когда сервер терминировала проверка указателя на NULL там, где он казалось бы, ну никак не может попасть в этот кусок кода, если этот указатель равен NULL, и заканчивая вообще странными проблемами с портабельностью. Например, инициализацию демона с вызовами отадочных syslog() в процессе:

openlog(...);
//daemonize here
for (i=0; i < 20; i++) /*we guaranted to have at least 20 descriptors */
close(i); /* close them as W.R.Stevens suggests */
...
socket(); bind(); listen();
...
select(); //in endless loop

С этим куском обнаружились интересные вещи - сервер порт то слушал, то не слушал! Причем в зависимости от уровня записи отладочной инфы в syslog было разное поведение, тестировалось на FreeBSD 4.11 и Linux 2.6.11 (Slackware 10.2). В процессе разборок, когда уже пришлось спрашивать у опытных товарищей (netch'у привет, ага), выяснилось, что это тут трюки в syslog - он этот дескриптор перехватывал, а на разных системах разная реализация - тут глюки есть, там нет. Мораль: не закрывайте в демоне дескрипторы, кроме 0,1 и 2 (эти лучше открыть на /dev/null).

Итак, под конец этот простенький чат (многоканальный, а-ля IRC) заработал нормально. Качество кода, имхо... э-э-э... среднеопенсорсное :) Точнее, оставил на закуску один специфический race condition, с подробным описанием бага и путей решения в последнем commit'е.

Архив с этой поделкой (исходники клиента, сервера, CVS-репозиторий сервера, протокол и отчет по практике) выложен тут. Вполне может пригодиться кому как курсовая, например. Или просто поизучать на простом примере, как пишется сетевой сервер по модели однопроцессной FSM (FAQ fido7.ru.unix.prog, appendix 1, п. 2) - в этом случае также полезно посмотреть изменения от ревизии к ревизии для изучения ошибок :)

P.S. Программу в работе у меня никто не смотрел. Даже не спрашивали толком :)

unix, программирование, лытдыбр

Previous post Next post
Up