Нейл Мэтью - Основы программирования в Linux
- Название:Основы программирования в Linux
- Автор:
- Жанр:
- Издательство:«БХВ-Петербург»
- Год:2009
- Город:Санкт-Петербург
- ISBN:978-5-9775-0289-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Нейл Мэтью - Основы программирования в Linux краткое содержание
В четвертом издании популярного руководства даны основы программирования в операционной системе Linux. Рассмотрены: использование библиотек C/C++ и стандартных средств разработки, организация системных вызовов, файловый ввод/вывод, взаимодействие процессов, программирование средствами командной оболочки, создание графических пользовательских интерфейсов с помощью инструментальных средств GTK+ или Qt, применение сокетов и др. Описана компиляция программ, их компоновка c библиотеками и работа с терминальным вводом/выводом. Даны приемы написания приложений в средах GNOME® и KDE®, хранения данных с использованием СУБД MySQL® и отладки программ. Книга хорошо структурирована, что делает обучение легким и быстрым.
Для начинающих Linux-программистов
Основы программирования в Linux - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
□ SOCK_STREAM
— это упорядоченный, надежный, основанный на соединении, двунаправленный поток байтов. В случае домена сокетов AF_INET
этот тип обмена данными по умолчанию обеспечивается TCP-соединением, которое устанавливается между двумя конечными точками потоковых сокетов при подключении. Данные могут передаваться в двух направлениях по линии связи сокетов. Протоколы TCP включают в себя средства фрагментации и последующей повторной сборки сообщений больших объемов и повторной передачи любых их частей, которые могли быть потеряны в сети.
□ SOCK_DGRAM
— дейтаграммный сервис. Вы можете использовать такой сокет для отправки сообщений с фиксированным (обычно небольшим) максимальным объемом, но при этом нет гарантии, что сообщение будет доставлено или что сообщения не будут переупорядочены в сети. В случае сокетов домена AF_INET
этот тип передачи данных обеспечивается дейтаграммами UDP (User Datagram Protocol, пользовательский протокол дейтаграмм).
Протокол, применяемый для обмена данными, обычно определяется типом сокета и доменом. Как правило, выбора нет. Параметр protocol
применяется в тех случаях, когда выбор все же предоставляется. Задание 0 позволяет выбрать стандартный протокол, используемый во всех примерах данной главы.
Системный вызов socket
возвращает дескриптор, во многом похожий на низкоуровневый файловый дескриптор. Когда сокет подключен к концевой точке другого сокета, для отправки и получения данных с помощью сокетов можно применять системные вызовы read
и write
с дескриптором сокета. Системный вызов close
используется для удаления сокетного соединения.
Адреса сокетов
Каждый домен сокетов требует своего формата адресов. В домене AF_UNIX
адрес описывается структурой sockaddr_un
, объявленной в заголовочном файле sys/un.h:
struct sockaddr_un {
sa_family_t sun_family; /* AF_UNIX */
char sun_path[]; /* Путь к файлу */
};
Для того чтобы адреса разных типов могли передаваться в системные вызовы для обработки сокетов, все адресные форматы описываются похожей структурой, которая начинается с поля (в данном случае sun_family
), задающего тип адреса (домен сокета). В домене AF_UNIX
адрес задается именем файла в поле структуры sun_path
.
В современных системах Linux тип sa_family_t
, описанный в стандарте X/Open как объявляемый в заголовочном файле sys/un.h, интерпретируется как тип short
. Кроме того, размер pathname
, задаваемого в поле sun_path
, ограничен (в Linux указывается 108 символов; в других системах может применяться именованная константа, например, UNIX_MAX_PATH
). Поскольку размер адресной структуры может меняться, многие системные вызовы сокетов требуют или предоставляют на выходе длину, которая будет использоваться для копирования конкретной адресной структуры.
В домене AF_INET
адрес задается с помощью структуры с именем sockaddr_in
, определенной в файле netinet/in.h, которая содержит как минимум следующие элементы:
struct sockaddr_in {
short int sin_family; /* AF_INET */
unsigned short int sin_port; /* Номер порта */
struct in_addr sin_addr; /* Интернет-адрес */
};
Структура IP-адреса типа in_addr определена следующим образом:
struct in_addr {
unsigned long int s_addr;
};
Четыре байта IP-адреса образуют одно 32-разрядное значение. Сокет домена AF_INET
полностью описывается IP-адресом и номером порта. С точки зрения приложения все сокеты действуют как файловые дескрипторы, и их адреса задаются уникальными целочисленными значениями.
Именование сокета
Для того чтобы сделать сокет (созданный с помощью вызова socket
) доступным для других процессов, серверная программа должна присвоить сокету имя. Сокеты домена AF_UNIX
связаны с полным именем файла в файловой системе, как вы видели в программе-примере server1. Сокеты домена AF_INET
связаны с номером IP-порта.
#include
int bind(int socket, const struct sockaddr *address, size_t address len);
Системный вызов bind
присваивает адрес, заданный в параметре address
, неименованному сокету, связанному с дескриптором сокета socket
. Длина адресной структуры передается в параметре address_len
:
Длина и формат адреса зависят от адресного семейства. В системном вызове bind
указатель конкретной адресной структуры должен быть приведен к обобщенному адресному типу (struct sockaddr*)
.
В случае успешного завершения bind
возвращает 0. Если он завершается аварийно, возвращается -1, и переменной errno
присваивается одно из значений, перечисленных в табл. 15.2.
Таблица 15.2
Значение errno |
Описание |
---|---|
EBADF |
Неверный файловый дескриптор |
ENOTSOCK |
Файловый дескриптор не ссылается на сокет |
EINVAL |
Файловый дескриптор ссылается на сокет, уже получивший имя |
EADDRNOTAVAIL |
Недопустимый адрес |
EADDINUSE |
У адреса уже есть связанный с ним сокет |
Для сокетов домена AF_UNIX есть несколько дополнительных значений |
|
EACCESS |
Невозможно создать имя в файловой системе из-за прав доступа |
ENOTDIR , ENAMETOOLONG |
Означает недопустимое имя файла |
Создание очереди сокетов
Для приема запросов на входящие соединения на базе сокетов серверная программа должна создать очередь для хранения ждущих обработки запросов. Формируется она с помощью системного вызова listen
.
#include
int listen(int socket, int backlog);
Система Linux может ограничить количество ждущих обработки соединений, которые могут храниться в очереди. В соответствии с этим максимумом вызов listen
задает длину очереди, равной backlog
. Входящие соединения, не превышающие максимальной длины очереди, сохраняются в ожидании сокета; последующим запросам на соединение будет отказано, и клиентская попытка соединения завершится аварийно. Этот механизм реализуется вызовом listen
для того, чтобы можно было сохранить ждущие соединения запросы, пока серверная программа занята обработкой запроса предыдущего клиента. Очень часто параметр backlog
равен 5.
Функция listen
вернет 0 в случае успешного завершения и -1 в случае ошибки. Как и для системного вызова bind
, ошибки могут обозначаться константами EBADF
, EINVAL
И ENOTSOCK
.
Прием запросов на соединение
После создания и именования сокета серверная программа может ждать запросы на выполнение соединения с сокетом с помощью системного вызова accept
:
Интервал:
Закладка: