Читаем Linux API. Исчерпывающее руководство полностью

При написании сетевых программ следует помнить: в каждой компьютерной архитектуре принято по-своему представлять некоторые типы данных. Мы уже отмечали, что целочисленные значения могут храниться с разным порядком следования байтов. Но существуют и другие особенности. Например, тип данных long в языке C может занимать как 32, так и 64 бита в зависимости от системы. В случае со структурами все только усложняется, ведь платформы задействуют различные правила выравнивания полей структуры по границам адреса, из-за чего величина сдвига между полями может варьироваться.

Из-за указанных отличий в представлении данных приложения, передающие информацию по сети между двумя гетерогенными (несовместимыми) системами, должны использовать некое общее соглашение относительно кодирования и декодирования этой информации. Процесс приведения данных к стандартному формату, подходящему для передачи по сети, называется маршалингом (англ. marshalling — «упорядочивание»). Существуют разные стандарты маршалинга, такие как XDR (External Data Representation — внешнее представление данных; см. RFC 1014), ASN.1-BER (Abstract Syntax Notation 1, см. http://www.itu.int/en/ITU-T/asn1/Pages/asn1_project.aspx), CORBA и XML. Обычно эти стандарты определяют строгий формат для каждого типа данных (описывая, например, порядок следования байтов и количество применяемых битов). Во время кодирования в подходящий формат данные маркируются с помощью одного или нескольких дополнительных полей, которые определяют их тип (и, возможно, длину).

Однако вместо маршалинга часто используется более простая методика: все передаваемые данные переводятся в текстовый вид, а отдельные элементы разделяются специальными символами (обычно символом новой строки). Одним из преимуществ такого подхода является то, что для отладки приложения можно задействовать программу telnet. Для этого достаточно следующей команды:

$ telnet host port

Затем можно вводить строчки текста, которые будут посланы приложению, и просматривать полученные ответы. Данная методика будет продемонстрирована в разделе 55.11.

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

Для работы с данными, передаваемыми с помощью потокового сокета и закодированными в виде разбитого на отдельные строки текста, удобно использовать функцию readLine(), представленную в листинге 55.1.

#include "read_line.h"

ssize_t readLine(int fd, void *buffer, size_t n);

Возвращает либо количество байтов, скопированных в buffer (не считая завершающего нулевого символа), либо 0, если обнаружен конец файла, либо -1 при ошибке

Функция readLine() считывает байты из файла, указанного дескриптором fd, пока не обнаруживает символ новой строки. Входящая последовательность байтов сохраняется в участке памяти, на который ссылается аргумент buffer; размер этого участка должен быть не меньше n байт. Возвращаемая строка всегда содержит в конце нулевой символ; таким образом, объем полученных данных не превышает (n — 1) байт. В случае успеха функция readLine() возвращает количество байтов, помещенных в buffer, не считая конечного нулевого символа.

Листинг 55.1. Построчное чтение данных

sockets/read_line.c

#include

#include

#include "read_line.h" /* Объявление readLine() */

ssize_t

readLine(int fd, void *buffer, size_t n)

{

ssize_t numRead; /* Сколько байтов было прочитано */

size_t totRead; /* Общее количество прочитанных байтов на этот момент */

char *buf;

char ch;

if (n <= 0 || buffer == NULL) {

errno = EINVAL;

return -1;

}

buf = buffer; /* Арифметика указателей не поддерживается для "void *" */

totRead = 0;

for (;;) {

numRead = read(fd, &ch, 1);

if (numRead == -1) {

if (errno == EINTR) /* Прерывание — > перезапускаем read() */

continue;

else

return -1; /* Какая-то другая ошибка */

} else if (numRead == 0) { /* Конец файла */

if (totRead == 0) /* Ничего не прочитано; возвращаем 0 */

return 0;

else

/* Прочитано какое-то количество байтов; добавляем '\0' */

break;

} else { /* На данном этапе 'numRead' должно быть равно 1 */

if (totRead < n — 1) { /* Отклоняем лишние байты: > (n — 1) */

totRead++;

*buf++ = ch;

}

if (ch == '\n')

break;

}

}

*buf = '\0';

return totRead;

}

sockets/read_line.c

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных