MyBooks.club
Все категории

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

На сайте mybooks.club вы можете бесплатно читать книги онлайн без регистрации, включая Марк Митчелл - Программирование для Linux. Профессиональный подход. Жанр: Программирование издательство -,. Доступна полная версия книги с кратким содержанием для предварительного ознакомления, аннотацией (предисловием), рецензиями от других читателей и их экспертным мнением.
Кроме того, на сайте mybooks.club вы найдете множество новинок, которые стоит прочитать.

Название:
Программирование для Linux. Профессиональный подход
Издательство:
-
ISBN:
-
Год:
-
Дата добавления:
17 сентябрь 2019
Количество просмотров:
290
Читать онлайн
Марк Митчелл - Программирование для Linux. Профессиональный подход

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

Марк Митчелл - Программирование для Linux. Профессиональный подход - описание и краткое содержание, автор Марк Митчелл, читайте бесплатно онлайн на сайте электронной библиотеки mybooks.club
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.

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

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

   rval =

    getpeername(connection, &socket_address, &address_length);

   assert(rval == 0);

   /* Вывод сообщения. */

   printf("connection accepted from %sn",

   inet_ntoa(socket_address.sin_addr));

  }


  /* Создание дочернего процесса для обработки запроса. */

  child_pid = fork();

  if (child_pid == 0) {

   /* Это дочерний процесс. Потоки stdin и stdout ему не нужны,

      поэтому закрываем их. */

   close(STDIN_FILENO);

   close(STDOUT_FILENO);

   /* Дочерний процесс не должен работать с серверным сокетом,

      поэтому закрываем его дескриптор. */

   close(server_socket);

   /* Обработка запроса. */

   handle_connection(connection);

   /* Обработка завершена. Закрываем соединение и завершаем

      дочерний процесс. */

   close(connection);

   exit(0);

  } else if (child_pid > 0) {

   /* Это родительский процесс. Дескриптор клиентского сокета

      ему не нужен. Переход к приему следующего запроса. */

   close(connection);

  } else

   /* Вызов функции fork() завершился неудачей. */

   system_error("fork");

 }

}

В файле server.c определены следующие функции.

■ Функция server_run() является телом сервера. Она запускает сервер и начинает принимать запросы на подключение, не завершаясь до тех пор, пока не произойдет серьезная ошибка. Сервер создает потоковый TCP-сокет (см. раздел 5.5.3, "Серверы").

Первый аргумент функции server_run определяет локальный адрес, по которому принимаются запросы. У компьютера может быть несколько адресов, каждый из которых соответствует определённому сетевому интерфейсу.[37] Данный аргумент ограничивает работу сервера конкретным интерфейсом или разрешает принимать запросы отовсюду, если равен INADDR_ANY.

Второй аргумент функции server_run() — это номер порта сервера. Если порт уже используется или является привилегированным, работа сервера завершится. Когда номер порта задан равным нулю. ОС Linux автоматически выберет неиспользуемый порт.

Для обработки каждого клиентского запроса сервер создает дочерний процесс с помощью функции fork() (см. раздел 3.2.2. "Функции fork() и exec()"), в то время как родительский процесс продолжает принимать новые запросы. Дочерний процесс вызывает функцию handle_connection(), после чего закрывает соединение и завершается.

■ Функция handle_connection() обрабатывает отдельный клиентский запрос, принимая в качестве аргумента дескриптор сокета. Функция читает данные из сокета и пытается интерпретировать их как HTTP-запрос на получение страницы.

Сервер обрабатывает только запросы протокола HTTP версий 1.0 и 1.1. Столкнувшись с иными протоколом или версией сервер возвращает HTTP-код 400 и сообщение bad_request_response. Сервер понимает только HTTP-метод GET. Если клиент запрашивает какой-то другой метод, сервер возвращает HTTP-код 501 и сообщение bad_method_response_template.

■ Если клиент послал правильно сформированный запрос GET, функция handle_connection() вызывает функцию handle_get(), которая обрабатывает запрос. Эта функция пытается загрузить серверный модуль, имя которого генерируется на основании имени запрашиваемой страницы. Например, когда клиент запрашивает страницу с именем "information", делается попытка загрузить модуль information.so. Если модуль не может быть загружен, функция handle_get() возвращает HTTP-код 404 и сообщение not_found_response_template.

В случае обращения к верной странице функция handle_get() возвращает клиенту HTTP-код 200, указывающий на успешную обработку запроса, и вызывает функцию module_generate(), содержащуюся в модуле. Последняя генерирует HTML-код Web-страницы и посылает его клиенту.

■ Функция server_run() регистрирует функцию clean_up_child_process() в качестве обработчика сигнала SIGCHLD. Обработчик просто очищает ресурсы завершившегося дочернего процесса (см. раздел 3.4.4. "Асинхронное удаление дочерних процессов").

11.2.4. Основная программа

В файле main.c (листинг 11.5) содержится функция main() сервера. Она отвечает за анализ аргументов командной строки и обнаружение ошибок в них, а также за конфигурирование и запуск сервера.

Листинг 11.5. (main.c) Главная серверная функция, выполняющая анализ аргументов командной строки

#include <assert.h>

#include <getopt.h>

#include <netdb.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

#include <unistd.h>

#include "server.h"


/* Описание длинных опций для функции getopt_long(). */

static const struct option long_options[] = {

 { "address",    1, NULL, 'a' },

 { "help",       0, NULL, 'h' },

 { "module-dir", 1, NULL, 'm' },

 { "port",       1, NULL, 'p' },

 { "verbose",    0, NULL, 'v' },

};


/* Описание коротких опций для функции getopt_long(). */

static const char* const short_options = "a:hm:p:v";


/* Сообщение о том, как правильно использовать программу. */

static const char* const usage_template =

 "Usage: %s { options }n"

 " -a, --address ADDR   Bind to local address (by default, bindn"

 "                      to all local addresses).n"

 " -h, --help           Print this information.n"

 " -m, --module-dir DIR Load modules from specified directoryn"

 "                      (by default, use executable directory).n"

 " -p, --port PORT      Bind to specified port.n"

 " -v, --verbose        Print verbose messages.n";


/* Вывод сообщения о правильном использовании программы

   и завершение работы. Если аргумент IS_ERROR не равен нулю,

   сообщение записывается в поток stderr и возвращается

   признак ошибки, в противном случае сообщение выводится в

   поток stdout и возвращается обычный нулевой код. */

static void print_usage(int is_error) {

 fprintf(is_error ? stderr : stdout, usage_template,

  program_name);

 exit(is_error ? 1 : 0);

}


int main(int argc, char* const argv[]) {

 struct in_addr local_address;

 uint16_t port;

 int next_option;


 /* Сохранение имени программы для отображения в сообщениях

    об ошибке. */

 program_name = argv[0];


 /* Назначение стандартных установок. По умолчанию сервер

    связан со всеми локальными адресами, и ему автоматически

    назначается неиспользуемый порт. */

 local_address.s_addr = INADDR_ANY;

 port = 0;

 /* He отображать развернутые сообщения. */

 verbose = 0;

 /* Загружать модули из каталога, в котором содержится

    исполняемый файл. */

 module_dir = get_self_executable_directory();

 assert(module_dir != NULL);


 /* Анализ опций. */

 do {

  next_option =

   getopt_long(argc, argv, short_options,

  long_options, NULL);

  switch (next_option) {

  case 'a':

   /* Пользователь ввел -a или --address. */

   {

    struct hostent* local_host_name;


    /* Поиск заданного адреса. */

    local_host_name = gethostbyname(optarg);

    if (local_host_name == NULL ||

     local_host_name->h_length == 0)

     /* He удалось распознать имя. */

     error(optarg, "invalid host name");

    else

     /* Введено правильное имя */

     local_address.s_addr =

      *((int*)(local_host_name->h_addr_list[0]));

   }

   break;

  case 'h':

   /* Пользователь ввёл -h или --help. */

   print_usage(0);

  case 'm':

   /* Пользователь ввел -m или --module-dir. */

   {

    struct stat dir_info;


    /* Проверка существования каталога */

    if (access(optarg, F_OK) != 0)

     error(optarg, "module directory does not exist");

    /* Проверка доступности каталога. */

    if (access(optarg, R_OK | X_OK) != 0)

     error(optarg, "module directory is not accessible");

    /* Проверка того, что это каталог. */

    if (stat(optarg, &dir_info) != 0 || !S_ISDIR(dir_info.st_mode))

     error(optarg, "not a directory");

    /* Все правильно. */

    module_dir = strdup(optarg);

   }

   break;

  case 'p':

   /* Пользователь ввел -p или --port. */

   {

    long value;

    char* end;


    value = strtol(optarg, &end, 10);

    if (*end != '')


Марк Митчелл читать все книги автора по порядку

Марк Митчелл - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки mybooks.club.


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

Отзывы читателей о книге Программирование для Linux. Профессиональный подход, автор: Марк Митчелл. Читайте комментарии и мнения людей о произведении.

Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*
Все материалы на сайте размещаются его пользователями.
Администратор сайта не несёт ответственности за действия пользователей сайта..
Вы можете направить вашу жалобу на почту librarybook.ru@gmail.com или заполнить форму обратной связи.