Вход/Регистрация
Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
вернуться

Кёртен Роб

Шрифт:

Функция MsgRead позволяет Вашему серверу считать nbytes байт данных из адресного пространства заблокированного клиента, начиная со смещения offset от начала клиентского буфера, в буфер, указанный параметром msg. Сервер не блокируется, а клиент не разблокируется. Функция MsgRead возвращает число байтов, которые были фактически считаны, или возвращает -1, если произошла ошибка.

Итак, давайте подумаем, как бы мы использовали эти возможности в нашем примере с вызовом write. Библиотечная функция write создает сообщение с заголовком и посылает его серверу файловой системы

fs-qnx4
. Сервер принимает небольшую часть сообщения с помощью MsgReceive, анализирует его и принимает решение, где разместить остальную часть сообщения — например, где-то в уже выделенном буфере дискового кэша.

Давайте рассмотрим пример.

Пример отправки сообщения серверу fs-qnx4 с непрерывным представлением данных.

Итак, клиент решил переслать файловой системе 4Кб данных. (Отметьте для себя, что Си-библиотека добавила к сообщению перед данными небольшой заголовок — чтобы потом можно было узнать, к какому типу принадлежал этот запрос. Мы еще вернемся к этому вопросу, когда будем говорить о составных сообщениях, а также — еще более детально — когда будем анализировать работу администраторов ресурсов.) Файловая система считывает только те данные (заголовок), которые будут ей необходимы для того, чтобы выяснить тип принятого сообщения:

// Часть заголовков, вымышлены для примера

struct _io_write {

 uint16_t type;

 uint16_t combine_len;

 int32_t nbytes;

 uint32_t xtype;

};

typedef union {

 uint16_t type;

 struct _io_read io_read;

 struct _io_write io_write;

 ...

} header_t;

header_t header; // Объявить заголовок

rcvid = MsgReceive(chid, &header, sizeof(header), NULL);

switch (header.type) {

 ...

case _IO_WRITE:

 number_of_bytes = header.io_write.nbytes;

 ...

Теперь сервер

fs-qnx4
знает, что в адресном пространстве клиента находится 4Кб данных (сообщение известило его об этом через элемент структуры nbytes), и что эти данные надо передать в буфер кэша. Теперь сервер
fs-qnx4
может сделать так:

MsgRead(rcvid, cache_buffer[index].data,

 cache_buffer[index].size, sizeof(header.io_write));

Обратите внимание, что операции приема сообщения задано смещение

sizeof(header.io_write)
— это сделано для того, чтобы пропустить заголовок, добавленный клиентской библиотекой. Мы предполагаем здесь, что
cache_buffer[index].size
(размер буфера кэша) равен 4096 (или более) байт.

Для записи данных в адресное пространство клиента есть аналогичная функция:

#include <sys/neutrino.h>

int MsgWrite(int rcvid, const void *msg, int nbytes,

 int offset);

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

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

Драйвер может иметь буфер размером 128Кб для обмена с аппаратурой посредством DMA, а сообщение пересылать в адресное пространство клиента по частям, используя функцию MsgWrite (разумеется, каждый раз увеличивая смещение на 128Кб). Когда будет передан последний фрагмент, можно будет вызывать MsgReply.

Передача нескольких фрагментов сообщения с помощью функции MsgWrite

Отметим, что функция MsgWrite позволяет вам записать различные компоненты данных в различные места, а затем либо просто разбудить клиента вызовом MsgReply:

MsgReply(rcvid, EOK, NULL, 0);

либо сделать это после записи заголовка в начало клиентского буфера:

MsgReply(rcvid, EOK, &header, sizeof(header));

  • Читать дальше
  • 1
  • ...
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: