Logo    
Деловая газета CitCity.ru CITKIT.ru - все об Open Source Форумы Все публикации Учебный центр Курилка
CitForum    CITForum на CD    Подписка на новости портала Море(!) аналитической информации! :: CITFORUM.RU
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

09.06.2017

Google
WWW CITForum.ru
С Новым годом!
2007 г.

Сокеты

Статья из серии "Программирование для Linux", журнал Linux Format

Андрей Боровский, symmetrica.net

В конкурсе на лучшую компьютерную идею всех времен и народов сокеты, без сомнения, могли бы рассчитывать на призовое место. Как и другие средства межпроцессного взаимодействия, рассмотренные в этой серии статей, сокеты впервые были реализованы именно на платформе Unix (4.2BSD), однако, концепция сокетов, как универсального средства обмена данными между процессами, оказалась настолько удачна, что все современные системы поддерживают, по крайней мере, некоторое подмножество сокетов. Причины успеха сокетов заключаются в их простоте и универсальности. Программы, обменивающиеся данными с помощью сокетов, могут работать в одной системе и в разных, используя для обмена данными как специальные объекты системы, так и сетевой стек. Как и каналы, сокеты используют простой интерфейс, основанный на «файловых» функциях read(2) и write(2) (открывая сокет, программа Unix получает дескриптор файла, благодаря которому можно работать с сокетами, используя файловые функции), но, в отличие от каналов, сокеты позволяют передавать данные в обоих направлениях, как в синхронном, так и в асинхронном режиме.

Большинство программистов используют для работы с сокетами различные библиотеки высокого уровня, однако, высокоуровневые библиотеки, как правило, не позволяют задействовать всю мощь и все многообразие сокетов. Наглядный пример многообразия – файловые сокеты. Программистам Windows должны быть знакомы сетевые сокеты, которые обычно организуют обмен данными с помощью протоколов семейства TCP/IP, однако в Unix есть и другие типы сокетов, специально предназначенные для обмена данными между локальными процессами.

Сокеты в файловом пространстве имен

Сокеты в файловом пространстве имен (file namespace, их еще называют «сокеты Unix») используют в качестве адресов имена файлов специального типа. Важной особенностью этих сокетов является то, что соединение с их помощью локального и удаленного приложений невозможно, даже если файловая система, в которой создан сокет, доступна удаленной операционной системе. В следующем фрагменте кода мы создаем сокет и связываем его с файлом socket.soc (это фрагмент программы сервера fsserver.c, которую вы найдете здесь):
sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sock < 0) {
perror("socket failed");
return EXIT_FAILURE;
}
srvr_name.sa_family = AF_UNIX;
strcpy(srvr_name.sa_data, "socket.soc");
if (bind(sock, &srvr_name, strlen(srvr_name.sa_data) +
sizeof(srvr_name.sa_family)) < 0) {
perror("bind failed");
return EXIT_FAILURE;
}

Константы и функции, необходимые для работы с сокетами в файловом пространстве имен, объявлены в файлах <sys/types.h> и <sys/socket.h>. Как и файлы, сокеты в программах представлены дескрипторами. Дескриптор сокета можно получить с помощью функции socket(2). Первый параметр этой функции – домен, к которому принадлежит сокет. Домен сокета обозначает тип соединения (а не доменное имя Интернета, как вы могли бы подумать). Домен, обозначенный константой AF_UNIX, соответствует сокетам в файловом пространстве имен. Второй параметр socket() определяет тип сокета. значение SOCK_DGRAM указывает датаграммный сокет (я предпочитаю этот вариант написания используемому в [1] «дейтаграммный»). Датаграммные сокеты осуществляют ненадежные соединения при передаче данных по сети и допускают широковещательную передачу данных. Другой часто используемый тип сокетов – SOCK_STREAM соответствует потоковым сокетам, реализующим соединения «точка-точка» с надежной передачей данных. Впрочем, в пространстве файловых имен датаграммные сокеты также надежны, как и потоковые сокеты. Третий параметр функции socket() позволяет указать протокол, используемый для передачи данных. Мы оставляем значение этого параметра равным нулю. В случае ошибки функция socket() возвращает -1.

После получения дескриптора сокета мы вызываем функцию bind(2), которая связывает сокет с заданным адресом (связывать сокет с адресом необходимо в программе-сервере, но не в клиенте). Первым параметром функции является дескриптор, а вторым – указатель на структуру sockaddr (переменная srvr_name), содержащую адрес, на котором регистрируется сервер (третий параметр функции – длина структуры, содержащей адрес). Вместо общей структуры sockaddr для сокетов Unix (сокетов в файловом пространстве имен) можно использовать специализированную структуру sockaddr_un. Поле sockaddr.sa_family позволяет указать семейство адресов, которым мы будем пользоваться. В нашем случае это семейство адресов файловых сокетов Unix AF_UNIX. Сам адрес семейства AF_UNIX (поле sa_data) представляет собой обычное имя файла сокета. После вызова bind() наша программа-сервер становится доступна для соединения по заданному адресу (имени файла).

При обмене данными с датаграммными сокетами мы используем не функции write() и read(), а специальные функции recvfrom(2) и sendto(2). Эти же функции могут применяться и при работе с потоковыми сокетами, но в соответствующем примере мы воспользуемся «сладкой парочкой» read()/write(). Для чтения данных из датаграммного сокета мы используем функцию recvfrom(2), которая по умолчанию блокирует программу до тех пор, пока на входе не появятся новые данные.

bytes = recvfrom(sock, buf, sizeof(buf), 0, &rcvr_name, &namelen);

Вызывая функцию recvfrom(), мы передаем ей указатель на еще одну структуру типа sockaddr, в которой функция возвращает данные об адресе клиента, запросившего соединение (в случае файловых сокетов этот параметр не несет полезной информации). Последний параметр функции recvfrom() – указатель на переменную, в которой будет возвращена длина структуры с адресом. Если информация об адресе клиента нас не интересует, мы можем передать значения NULL в предпоследнем и последнем параметрах. По завершении работы с сокетом мы закрываем его с помощью «файловой» функции close(). Перед выходом из программы-сервера следует удалить файл сокета, созданный в результате вызова socket(), что мы и делаем с помощью функции unlink().

Если программа-сервер показалась вам простой, то программа-клиент (fsclient.c) будет еще проще. Мы открываем сокет с помощью функции socket() и передаем данные (тестовую строку) серверу с помощью «напарника» recvfrom(), функции sendto(2):

srvr_name.sa_family = AF_UNIX;
strcpy(srvr_name.sa_data, SOCK_NAME);
strcpy(buf, "Hello, Unix sockets!");
sendto(sock, buf, strlen(buf), 0, &srvr_name,
strlen(srvr_name.sa_data) + sizeof(srvr_name.sa_family));

Первый параметр функции sendto() – дескриптор сокета, второй и третий параметры позволяют указать адрес буфера для передачи данных и его длину. Четвертый параметр предназначен для передачи дополнительных флагов. Предпоследний и последний параметры несут информацию об адресе сервера и его длине, соответственно. Если при работе с датаграммными сокетами вызвать функцию connect(2) (см. ниже), то можно не указывать адрес назначения каждый раз (достаточно указать его один раз, как параметр функции connect()). Перед вызовом функции sendto() нам надо заполнить структуру sockaddr (переменную srvr_name) данными об адресе сервера. После окончания передачи данных мы закрываем сокет с помощью close(). Если вы запустите программу-сервер, а затем программу-клиент, то сервер распечатает тестовою строку, переданную клиентом.

Парные сокеты

Сокеты в файловом пространстве имен похожи на именованные каналы тем, что для идентификации сокетов используются файлы специального типа. В мире сокетов есть и аналог неименованных каналов – парные сокеты (socket pairs). Как и не именованные каналы, парные сокеты создаются парами и не имеют имен. Естественно, что область применения парных сокетов – та же, что и у неименованных каналов, - взаимодействие между родительским и дочерним процессом. Так же как и в случае неименованного канала, один из дескрипторов используется одним процессом, другой – другим. В качестве примера использования парных сокетов мы рассмотрим программу sockpair.c, создающую два процесса с помощью fork(). Дочерние процессы sockpair.c используют парные сокеты для обмена вежливым английским приветствием.
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#define STR1 "How are you?"
#define STR2 "I'm ok, thank you."
#define BUF_SIZE 1024
int main(int argc, char ** argv)
{ int sockets[2];
char buf[BUF_SIZE];
int pid;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
perror("socketpair() failed");
return EXIT_FAILURE;
}
pid = fork();
if (pid != 0) {
close(sockets[1]);
write(sockets[0], STR1, sizeof(STR1));
read(sockets[0], buf, sizeof(buf));
printf("%s\n", buf);
close(sockets[0]);
} else {
close(sockets[0]);
read(sockets[1], buf, sizeof(buf));
printf("%s\n", buf);
write(sockets[1], STR2, sizeof(STR2));
close(sockets[1]);
}
}

Парные сокеты создаются функцией socketpair(2). У функции socketpair() четыре параметра. Первые три параметра функции те же, что и у socket(), а четвертым параметром является массив из двух переменных, в которых возвращаются дескрипторы. Дескрипторы сокетов, возвращенные socketpair(), уже готовы к передаче данных, так что мы сразу можем применять к ним функции read()/write(). После вызова fork() каждый процесс получает оба дескриптора, один из которых он должен закрыть. Для закрытия сокета мы используем функцию close().

При взгляде на интерфейс программирования парных сокетов может возникнуть вопрос, а почему собственно эти функции относятся к сокетам? Ведь при работе с ними мы не используем ни адреса, ни модель клиент-сервер. Это верно, но заметьте, что функции socketpair() передаются значения домена и типа сокета, так что и формально, и с точки зрения реализации в системе мы используем настоящие сокеты. Следует отметить, что указание домена в функции socketpair() выглядит явно излишне, поскольку для этой функции система поддерживает только сокеты в домене AF_UNIX (вполне логичное ограничение, если учесть, что парные сокеты не имеют имен и предназначены для обмена данными между родственными процессами).

Сетевые сокеты

Мы переходим к рассмотрению самого важного и универсального типа сокетов – сетевых сокетов. Думаю, что о значении, которое имеют сетевые сокеты в Unix-системах, распространяться не нужно. Даже если вы пишете систему приложений, предназначенных для работы на одном компьютере, рассмотрите возможность использования сетевых сокетов для обмена данными между этими приложениями. Возможно, в будущем ваш программный комплекс наберет мощь и возникнет необходимость распределить его компоненты на нескольких машинах.

Использование сетевых сокетов сделает процесс масштабирования проекта безболезненным. Впрочем, у сетевых сокетов есть и недостатки. Даже если сокеты используются для обмена данными на одной и той же машине, передаваемые данные должны пройти все уровни сетевого стека, что отрицательно сказывается на быстродействии и нагрузке на систему.

В качестве примера мы рассмотрим комплекс из двух приложений, клиента и сервера, использующих сетевые сокеты для обмена данными. Текст программы сервера вы найдете в файле netserver.c, ниже мы приводим некоторые фрагменты. Прежде всего, мы должны получить дескриптор сокета:

sock = socket(AF_INET, SOCK_STREAM, 0);
if (socket < 0) {
printf("socket() failed: %d\n", errno);
return EXIT_FAILURE;
}

В первом параметре функции socket() мы передаем константу AF_INET, указывающую на то, что открываемый сокет должен быть сетевым. Значение второго параметра требует, чтобы сокет был потоковым. Далее мы, как и в случае сокета в файловом пространстве имен, вызываем функцию bind():

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
printf("bind() failed: %d\n", errno);
return EXIT_FAILURE;
}

Переменная serv_addr, - это структура типа sockaddr_in. Тип sockaddr_in специально предназначен для хранения адресов в формате Интернета. Самое главное отличие sockaddr_in от sockaddr_un – наличие параметра sin_port, предназначенного для хранения значения порта. Функция htons() переписывает двухбайтовое значение порта так, чтобы порядок байтов соответствовал принятому в Интернете (см. врезку). В качестве семейства адресов мы указываем AF_INET (семейство адресов Интернета), а в качестве самого адреса – специальную константу INADDR_ANY. Благодаря этой константе наша программа сервер зарегистрируется на всех адресах той машины, на которой она выполняется.

Остроконечники и тупоконечники

Именно так переводятся на русский язык термины little-endian и big-endian. В компьютерной литературе эти термины обозначают порядок байтов, используемый процессором для представления простых многобайтовых типов (например, 32-битного целого). В оригинале же (то есть в сказочной повести Дж. Свифта «Гулливер в стране лилипутов») так именовались враждебные общественные течения, приверженцы которых придерживались противоположных взглядов на порядок очистки яйца от скорлупы. Разногласия между остроконечниками и тупоконечниками даже стали причинной войны между Лилипутией и враждебным государством Блефуску. Впрочем, в компьютерном мире проблемы порядка байтов могут достигать совсем не лилипутских размеров. На процессорах Intel порядок байтов остроконечный, а, например, в системах MacOS X – Power PC Sun SPARC - тупоконечный (если учесть, что Apple отказалась от PowerPC, а Sun заменяет RISC-архитектуры оптеронами, получится, что остроконечники побеждают). Однако протоколы Интернета используют «тупоконечный» порядок байтов. Для того чтобы избежать путаницы, во всех системах, включая «тупоконечников» рекомендуется использовать функцию htons(). Эта функция «знает» порядок байтов в системе и, если нужно, приводит его в соответствие с принятым в протоколах TCP/IP. В русскоязычном Интернете одно время кочевала статья, в которой утверждалась (впрочем, шутливо), что чуждый для Intel порядок байтов и вызванная этим необходимость в дополнительной операции перестановки являются результатом заговора со стороны гигантских софтверных компаний. В книге [1] используются термины «прямой порядок байтов» для little-endian и «обратный порядок байтов» для big-endian.

Чтобы понять, что мы должны делать дальше, давайте вспомним, как работает сетевая подсистема Unix и, в данном случае, любой другой ОС. Сетевой сервер должен уметь выполнять запросы множества клиентов одновременно (наш сервер netserver.c фактически может обработать запрос только одного клиента, но речь сейчас идет об общем случае). При этом в соединениях «точка-точка», например, при использовании потоковых сокетов, для каждого клиента у сервера должен быть открыт отдельный сокет. Из этого следует, что мы не должны устанавливать соединение с клиентом через сам сокет sock, предназначенный для прослушивания входящих запросов (обычно, при использовании сетевых сокетов мы и не можем этого сделать), иначе все другие попытки соединиться с сервером по указанному адресу и порту будут заблокированы. Вместо этого мы вызываем функцию listen(2), которая переводит сервер в режим ожидания запроса на соединение:

listen(sock, 1);

Второй параметр listen() – максимальное число соединений, которые сервер может обрабатывать одновременно. Далее мы вызываем функцию accept(2), которая устанавливает соединение в ответ на запрос клиента:

newsock = accept(sock, (struct sockaddr *) &cli_addr, &clen);
if (newsock < 0) {
printf("accept() failed: %d\n", errno);
return EXIT_FAILURE;
}

Получив запрос на соединение, функция accept() возвращает новый сокет, открытый для обмена данными с клиентом, запросившим соединение. Сервер как бы перенаправляет запрошенное соединение на другой сокет, оставляя сокет sock свободным для прослушивания запросов на установку соединения. Второй параметр функции accept() содержит сведения об адресе клиента, запросившего соединение, а третий параметр указывает размер второго. Так же как и при вызове функции recvfom(), мы можем передать NULL в последнем и предпоследнем параметрах. Для чтения и записи данных сервер использует функции read() и write(), а для закрытия сокетов, естественно, close(). В программе-клиенте (netclient.c) нам, прежде всего, нужно решить задачу, с которой мы не сталкивались при написании сервера, а именно выполнить преобразование доменного имени сервера в его сетевой адрес. Разрешение доменных имен выполняет функция gethostbyname():

server = gethostbyname(argv[1]);
if (server == NULL) {
printf("Host not found\n");
return EXIT_FAILURE;
}

Функция получает указатель на строку с Интернет-именем сервера (например, www.unix.com или 192.168.1.16) и возвращает указатель на структуру hostent (переменная server), которая содержит имя сервера в приемлемом для дальнейшего использования виде. При этом, если необходимо, выполняется разрешение доменного имени в сетевой адрес. Далее мы заполняем поля переменной serv_addr (структуры sockaddr_in) значениями адреса и порта:

serv_addr.sin_family = AF_INET;
strncpy((char *)&serv_addr.sin_addr.s_addr,
(char *)server->h_addr, server->h_length);
serv_addr.sin_port = htons(port);

Программа-клиент открывает новый сокет с помощью вызова функции socket() аналогично тому, как это делает сервер (дескриптор сокета, который возвращает socket() мы сохраним в переменной sock), и вызывает функцию connect(2) для установки соединения:

if (connect(sock, &serv_addr, sizeof(serv_addr)) < 0) {
printf("connect() failed: %d", errno);
return EXIT_FAILURE;
}

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

На протяжении этой статьи мы несколько раз упоминали не-блокирующие сокеты. Остановимся на них немного подробнее. О не-блокирующих сокетах вам нужно знать, прежде всего, то, что ими можно не пользоваться. Благодаря многопоточному (многопрограммному) программированию мы можем использовать блокирующие сокеты во всех ситуациях (и тогда, когда нам нужно обрабатывать несколько сокетов одновременно, и тогда, когда нам требуется возможность прервать операцию, выполняемую над сокетом). Рассмотрим, тем не менее, две функции, необходимые для работы с не-блокирующими сокетами. По умолчанию функция socket() создает блокирующий сокет. Чтобы сделать его не- блокирующим, мы используем функцию fcntl(2):

sock = socket(PF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);

Теперь любой вызов функции read() для сокета sock будет возвращать управление сразу же. Если на входе сокета нет данных для чтения, функция read() вернет значение EAGAIN. Для поверки состояния не-блокирующих сокетов можно воспользоваться функцией select(2). Функция select() способна проверять состояние нескольких дескрипторов сокетов (или файлов) сразу. Первый параметр функции – количество проверяемых дескрипторов. Второй, третий и четвертый параметры функции представляют собой наборы дескрипторов, которые следует проверять, соответственно, на готовность к чтению, записи и на наличие исключительных ситуаций. Сама функция select() – блокирующая, она возвращает управление, если хотя бы один из проверяемых сокетов готов к выполнению соответствующей операции. В качестве последнего параметра функции select() можно указать интервал времени, по прошествии которого она вернет управление в любом случае. Вызов select() для проверки наличия входящих данных на сокете sock может выглядеть так:

fd_set set;
struct timeval interval;
FD_SET(sock, &set);
tv.tv_sec = 1;
tv.tv_usec = 500000;
...
select(1, &set, NULL, NULL, &tv);
if (FD_ISSET(sock, &set) {
// Есть данные для чтения
}

Все, что касается функции select() теперь объявляется в заголовочном файле <sys/select.h> (раньше объявления элементов функции select() были разбросаны по файлам <sys/types.h>, <sys/time.h> и <stdlib.h>). В приведенном фрагменте кода FD_SET и FD_ISSET – макросы, предназначенные для работы с набором дескрипторов fd_set.

На этом мы закончим знакомство с увлекательным миром межпроцессного взаимодействия Linux. Следующая статья будет посвящена управлению процессами, сигналам и потокам.

Литература:

1.обратноСтивенс У., UNIX: Разработка сетевых приложений. - СПб.: Питер, 2004
2.обратноW. R. Stevens, S. A. Rago, Advanced Programming in the UNIX® Environment: Second Edition, Addison Wesley Professional, 2005

Исходники программы

Подписка на новости IT-портала CITForum.ru
(библиотека, CITKIT.ru, CitCity)

Новые публикации:

24 декабря

CITKIT.ru:

  • Новогодние поздравления
  • Сергей Кузнецов. Цикл Операционные системы: Ностальгия по будущему:

  • Алексей Федорчук. OpenSolaris 2008.11 Release

  • Сергей Голубев:

  • Евгений Чайкин aka StraNNik (Блогометки):

    17 декабря

  • С.Д.Кузнецов. Базы данных. Вводный курс

    10 декабря

    CITKIT.ru:

  • OpenSolaris 2008.11 Release

  • Альтернативные ОС: две грустные истории (С.Кузнецов)
  • Nokia N810 — доведение до ума
  • CitCity:

  • Платформа 2009: заоблачные перспективы Microsoft

    4 декабря

  • Лекция С.Д.Кузнецова Понятие модели данных. Обзор разновидностей моделей данных

    CITKIT.ru:

  • OpenSolaris 2008.11 Release. Первые впечатления

  • Linux vs FreeBSD: продолжим "Священные войны"?

  • Nokia N810 as is

  • Индульгенция для FOSS

  • Друзья СПО'2008

    26 ноября

  • Нечеткое сравнение коллекций: семантический и алгоритмический аспекты

    CitCity:

    CITKIT.ru:

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • 19 ноября

  • Проблемы экономики производства крупных программных продуктов

  • Язык модификации данных формата XML функциональными методами

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Заметки к книге:

  • FreeBSD: монтирование сменных устройств и механизм HAL
  • Текстовый редактор ee

    12 ноября

  • Правило пяти минут двадцать лет спустя, и как флэш-память изменяет правила (Гоц Грейф, перевод: Сергей Кузнецов)

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:
  • OSS в России: взгляд правоведа (В.Житомирский)

  • Новая статья из цикла С.Голубева "Железный марш":

    29 октября

  • О некоторых задачах обратной инженерии

  • Веб-сервисы и Ruby

  • Тестирование web-приложений с помощью Ruby

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

  • PuppyRus Linux - беседа с разработчиком (С.Голубев)

  • Сергей Кузнецов. Заметка не про Linux

    22 октября

  • Обзор методов описания встраиваемой аппаратуры и построения инструментария кросс-разработки

    CITKIT.ru:

  • Сергей Кузнецов. Почему я равнодушен к Linux

  • Глава из книги А.Федорчука
    Сага о FreeBSD:
  • Что надо иметь
    3. Базовые познания

    CitCity:

  • Управление IT-инфраструктурой на основе продуктов Microsoft

    15 октября

  • Методы бикластеризации для анализа интернет-данных

    CitCity:

  • Разъемы на ноутбуках: что они дают и зачем их так много?
  • AMD Puma и Intel Centrino 2: кто лучше?

    CITKIT.ru:

  • Новый цикл статей С.Голубева
    Железный марш:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    8 октября

  • Автоматизация тестирования web-приложений, основанных на скриптовых языках
  • Опыт применения технологии Azov для тестирования библиотеки Qt3

    Обзоры журнала Computer:

  • SOA с гарантией качества
  • Пикоджоуль ватт бережет
  • ICT и всемирное развитие

    CitCity:

  • Пиррова победа корпорации Microsoft

    CITKIT.ru:

  • Главы из книги А.Федорчука
    Сага о FreeBSD:

    Статья из архива:

  • Я живу в FreeBSD (Вадим Колонцов)

    Новые Блогометки:

  • Перекройка шаблона Blogger или N шагов к настоящему
  • Blogger. Comment style
  • Screenie или глянцевый снимок экрана

    2 октября

    CITKIT.ru:

  • Сага о FreeBSD (А. Федорчук)

    Zenwalk: пакет недели

  • Банинг — интеллектуальное развлечение (С.Голубев)

    CitCity:

    25 сентября

  • Клермонтский отчет об исследованиях в области баз данных

    CITKIT.ru:

  • Пользователям просьба не беспокоиться... (В.Попов)

  • Снова про ZFS: диск хорошо, а два лучше
  • Командная оболочка tcsh (А.Федорчук)

    Zenwalk: пакет недели

    17 сентября

  • T2C: технология автоматизированной разработки тестов базовой функциональности программных интерфейсов
  • Технология Azov автоматизации массового создания тестов работоспособности

    CITKIT.ru:

  • FreeBSD: ZFS vs UFS, и обе-две — против всех (А.Федорчук)

    Zenwalk: пакет недели

  • Дачнет — практика без теории (С.Голубев)

    10 сентября

  • За чем следить и чем управлять при работе приложений с Oracle
  • Планировщик заданий в Oracle
    (В.Пржиялковский)

    CITKIT.ru:

  • Microsoft: ответный "боян" (С.Голубев)

  • Причуды симбиоза, или снова "сделай сам" (В.Попов)

  • Файловые системы современного Linux'а: последнее тестирование
  • Zsh. Введение и обзор возможностей
    (А.Федорчук)

    Описания пакетов Zenwalk: Zsh, Thunar, Thunar-bulk-rename, Xfce4-places-plugin, Xfce4-fsguard-plugin

    Блогометки:

  • Google Chrome
  • Лончер для ASUS Eee PC 701

    3 сентября

    CITKIT.ru:

  • Заметки о ядре (А.Федорчук):

    Добавлены описания пакетов Zenwalk: Galculator, Screenshot, Gnumeric, Pidgin

    В дискуссинном клубе:

  • И еще о Википедии и Google Knol

  • Лекция для начинающего линуксоида (С.Голубев)

    26 августа

  • Транзакционная память (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Открыт новый проект Zenwalk: пакет недели

  • Статья Текстовые процессоры и их быстродействие: конец еще одной легенды?

    21 августа

    CITKIT.ru:

  • Почему школам следует использовать только свободные программы (Ричард Столлман)
  • Беседа Сергея Голубева с учителем В.В.Михайловым

  • Википедия или Гуглезнание? Приглашение к обсуждению (Алексей Федорчук)
  • Народная энциклопедия от Google (StraNNik)

  • Обзор Mandriva 2009.0 Beta 1 Thornicrofti
  • Новичок в Линукс: Оптимизируем Mandriva 2008.1

  • Книга Zenwalk. Приобщение к Linux:

    13 августа

    CitCity:

  • Мирный Atom на службе человеку. Обзор платы Intel D945GCLF с интегрированным процессором
  • Обзор процессоров Intel Atom 230 на ядре Diamondville

  • iPhone - год спустя. Скоро и в России?

    CITKIT.ru:

  • Интермедия 3.4. GRUB: установка и настройка (из книги Zenwalk. Приобщение к Linux)

    6 августа

  • СУБД с хранением данных по столбцами и по строкам: насколько они отличаются в действительности? (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • Интермедия 2.2. Что неплохо знать для начала (из книги Zenwalk. Приобщение к Linux)

  • И снова про шрифты в Иксах (А.Федорчук)

  • 20 самых быстрых и простых оконных менеджеров для Linux

  • Дело о трех миллиардах (С.Голубев)

    30 июля

  • OLTP в Зазеркалье (Пересказ: С. Кузнецов)

    CitCity:

  • Будущее BI в облаках?
  • Тиражные приложения и заказная разработка. Преимущества для заказчика
  • Дискуссия со сторонниками заказной разработки

    CITKIT.ru:

  • Новые главы книги Zenwalk. Приобщение к Linux:
  • Глава 8. Пакеты: средства установки, системы управления, системы построения
  • Глава 9. Zenwalk: репозитории, пакеты, методы установки

    23 июля

    CITKIT.ru:

  • Все против всех. 64 vs 32, Intel vs AMD, tmpfs vs ext3
  • Две головы от Intel

  • Zenwalk: обзор штатных приложений (глава из книги "Zenwalk. Приобщение к Linux")

  • Нормально, Григорий...

    16 июля

    Обзоры журнала Computer:

  • Перспективы и проблемы программной инженерии в XXI веке
  • Большие хлопоты с большими объемами данных
  • Перспективы наноэлектроники

    CITKIT.ru:

  • Интермедия о лицензиях (А.Федорчук. "Zenwalk. Приобщение к Linux")

  • Есть ли будущее у KDE?

  • Linux в школе: альтернативный вариант в задачах

  • Шифр (приключения агента Никодима)

    10 июля

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия вступительная. Linux или GNU/Linux? Как вас теперь называть?
  • Глава 5. Среда Xfce
  • Глава 6. Xfce: приложения и плагины

  • ZUR (Zenwalk User Repository) FAQ

    2 июля

  • Персистентность данных в объектно-ориентированных приложениях (С. Кузнецов)

    CITKIT.ru:

  • Новые разделы книги А. Федорчука Zenwalk. Приобщение к Linux:
  • Интермедия 1.2. Дорога к Zenwalk'у. Период бури и натиска
  • Интермедия 3.3. Немного о Linux'е и "железе"
  • Глава 4. Настройка: инструментами и руками
  • Интермедия 4.1. Zenpanel и конфиги: поиски корреляции

  • Интервью с Жан-Филиппом Гийоменом, создателем дистрибутива Zenwalk

  • Linux в школе: первые итоги (С. Голубев)

    25 июня

    CITKIT.ru:

  • Zenwalk. Приобщение к Linux (А. Федорчук)

  • Логика и риторика (С.Голубев)

  • Технология Tru64 AdvFS

  • Ханс Райзер предлагает отвести полицейских к телу Нины

    18 июня

  • Проекты по управлению данными в Google (Пересказ: С. Кузнецов)

    CITKIT.ru:

  • ОС и поддержка "железа": мифы и реальность (А. Федорчук)

  • Linux в школе: другие дистрибутивы

  • Пинок (С. Голубев)

    4 июня

  • Ландшафт области управления данными: аналитический обзор (С. Кузнецов)

    CITKIT.ru:

  • Linux в школе: слово заинтересованным лицам

  • SlackBuild: пакеты своими руками

  • Linux от компании Novell. Установка и обзор openSUSE Linux

    Все публикации >>>




  • IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

    Информация для рекламодателей Пресс-релизы — pr@citcity.ru
    Послать комментарий
    Информация для авторов
    Rambler's Top100 This Web server launched on February 24, 1997
    Copyright © 1997-2017 CIT, © 2001-2017 CIT Forum
    Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...