Марк Митчелл - Программирование для Linux. Профессиональный подход

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Программирование для Linux. Профессиональный подход"
Описание и краткое содержание "Программирование для Linux. Профессиональный подход" читать бесплатно онлайн.
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.
Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.
" </body>\n"
"</html>\n";
/* HTTP-ответ, заголовок и шаблон страницы на случай,
когда запрашиваемый документ не найден. */
static char* not_found_response_template =
"HTTP/1.0 404 Not Found\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Not Found</h1>\n"
" <p>The requested URL %s was not found on this server.</p>\n"
" </body>\n"
"</html>\n";
/* HTTP-ответ, заголовок к шаблон страницы на случай,
когда запрашивается непонятный метод */
static char* bad_method_response_template =
"HTTP/1.0 501 Method Not Implemented\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Method Not Implemented</h1>\n"
" <p>The method %s is not implemented by this server.</p>\n"
" </body>\n"
"</html>\n";
/* Обработчик сигнала SIGCHLD, удаляющий завершившиеся
дочерние процессы. */
static void clean_up_child_process(int signal_number) {
int status;
wait(&status);
}
/* Обработка HTTP-запроса "GET" к странице PAGE и
запись результата в файл с дескриптором CONNECTION_FD. */
static void handle_get(int connection_fd, const char* page) {
struct server_module* module = NULL;
/* Убеждаемся, что имя страницы начинается с косой черты и
не содержит других символов косой черты, так как
подкаталоги не поддерживаются. */
if (*page == '/' && strchr(page + 1, '/') == NULL) {
char module_file_name[64];
/* Имя страницы правильно. Формируем имя модуля, добавляя
расширение ".so" к имени страницы. */
snprintf(module_file_name, sizeof(module_file_name),
"%s.so", page + 1);
/* Попытка открытия модуля. */
module = module_open(module_file_name);
}
if (module == NULL) {
/* Имя страницы неправильно сформировано или не удалось
открыть модуль с указанным именем. В любом случае
возвращается HTTP-ответ "404. Not Found". */
char response[1024];
/* Формирование ответного сообщения. */
snprintf(response, sizeof(response),
not_found_response_template, page);
/* Отправка его клиенту. */
write(connection_fd, response, strlen(response));
} else {
/* Запрашиваемый модуль успешно загружен. */
/* Выдача HTTP-ответа, обозначающего успешную обработку
запроса, и HTTP-заголовка для HTML-страницы. */
write(connection_fd, ok_response, strlen(ok_response));
/* Вызов модуля, генерирующего HTML-код страницы и
записывающего этот код в указанный файл. */
(*module->generate_function)(connection_fd);
/* Работа с модулем окончена. */
module_close(module);
}
}
/* Обработка клиентского запроса на подключение. */
static void handle_connection(int connection_fd) {
char buffer[256];
ssize_t bytes_read;
/* Получение данных от клиента. */
bytes_read =
read(connection_fd, buffer, sizeof(buffer) — 1);
if (bytes_read > 0) {
char method[sizeof(buffer)];
char url[sizeof(buffer)];
char protocol[sizeof(buffer)];
/* Часть данных успешно прочитана. Завершаем буфер
нулевым символом, чтобы его можно было использовать
в строковых операциях. */
buffer[bytes_read] = '\0';
/* Первая строка, посылаемая клиентом, -- это HTTP-запрос.
В запросе указаны метод, запрашиваемая страница и
версия протокола. */
sscanf(buffer, "%s %s %s", method, url, protocol);
/* В заголовке, стоящем после запроса, может находиться
любая информация. В данной реализации HTTP-сервера
эта информация не учитывается. Тем не менее необходимо
прочитать все данные, посылаемые клиентом. Данные читаются
до тех пор, пока не встретится конец заголовка,
обозначаемый пустой строкой. В HTTP пустой строке
соответствуют символы CR/LF. */
while (strstr(buffer, " \r\n\r\n") == NULL)
bytes_read = read(connection_fd, buffer, sizeof(buffer));
/* Проверка правильности последней операции чтения.
Если она не завершилась успешно, произошел разрыв
соединения, поэтому завершаем работу. */
if (bytes_read == -1) {
close(connection_fd);
return;
}
/* Проверка поля версии. Сервер понимает протокол HTTP
версий 1.0 и 1.1. */
if (strcmp(protocol, "HTTP/1.0") &&
strcmp(protocol, "HTTP/1.1")) {
/* Протокол не поддерживается. */
write(connection_fd, bad_request_response,
sizeof(bad_request_response));
} else if (strcmp (method, "GET")) {
/* Сервер реализует только метод GET, а клиент указал
другой метод. */
char response[1024];
snprintf(response, sizeof(response),
bad_method_response_template, method);
write(connection_fd, response, strlen(response));
} else
/* Корректный запрос. Обрабатываем его. */
handle_get(connection_fd, url);
} else if (bytes_read == 0)
/* Клиент разорвал соединение, не успев отправить данные.
Ничего не предпринимаем */
;
else
/* Операция чтения завершилась ошибкой. */
system_error("read");
}
void server_run(struct in_addr local_address, uint16_t port) {
struct sockaddr_in socket_address;
int rval;
struct sigaction sigchld_action;
int server_socket;
/* Устанавливаем обработчик сигнала SIGCHLD, который будет
удалять завершившееся дочерние процессы. */
memset(&sigchld_action, 0, sizeof(sigchld_action));
sigchld_action.sa_handler = &clean_up_child_process;
sigaction(SIGCHLD, &sigchld_action, NULL);
/* Создание TCP-сокета */
server_socket = socket(PF_INET, SOCK_STREAM, 0);
if (server_socket == -1) system_error("socket");
/* Создание адресной структуры, определяющей адрес
для приема запросов. */
memset(&socket_address, 0, sizeof(socket_address));
socket_address.sin_family = AF_INET;
socket_address.sin_port = port;
socket_address.sin_addr = local_address;
/* Привязка сокета к этому адресу. */
rval =
bind(server_socket, &socket_address,
sizeof(socket_address));
if (rval != 0)
system_error("bind");
/* Перевод сокета в режим приема запросов. */
rval = listen(server_socket, 10);
if (rval != 0)
system_error("listen");
if (verbose) {
/* В режиме развернутых сообщений отображаем адрес и порт,
с которыми работает сервер. */
socklen_t address_length;
/* Нахождение адреса сокета. */
address_length = sizeof(socket_address);
rval =
getsockname(server_socket, &socket_address, &address_length);
assert(rval == 0);
/* Вывод сообщения. Номер порта должен быть преобразован
из сетевого (обратного) порядка следования байтов
в серверный (прямой). */
printf("server listening on %s:%d\n",
inet_ntoa(socket_address.sin_addr),
(int)ntohs(socket_address.sin_port));
}
/* Бесконечный цикл обработки запросов. */
while (1) {
struct sockaddr_in remote_address;
socklen_t address_length;
int connection;
pid_t child_pid;
/* Прием запроса. Эта функция блокируется до тех пор, пока
не поступит запрос. */
address_length = sizeof(remote_address);
connection = accept(server_socket, &remote_address,
&address_length);
if (connection == -1) {
/* Функция завершилась неудачно. */
if (errno == EINTR)
/* Функция была прервана сигналом. Повторная попытка. */
continue;
else
/* Что-то случилось. */
system_error("accept");
}
/* Соединение установлено. Вывод сообщения, если сервер
работает в режиме развернутых сообщений. */
if (verbose) {
socklen_t address_length;
/* Получение адреса клиента. */
address_length = sizeof(socket_address);
rval =
getpeername(connection, &socket_address, &address_length);
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Программирование для Linux. Профессиональный подход"
Книги похожие на "Программирование для Linux. Профессиональный подход" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Марк Митчелл - Программирование для Linux. Профессиональный подход"
Отзывы читателей о книге "Программирование для Linux. Профессиональный подход", комментарии и мнения людей о произведении.