Пример: функция приема сообщений в случае сокета

Пример: функция приема сообщений в случае сокета

Часто оказывается удобным отправлять и получать сообщения в виде единых блоков. Как было показано в главе 11, каналы позволяют это сделать. Однако в случае сокетов требуется создание заголовка, содержащего размер сообщения, за которым следует само сообщение. Для приема таких сообщений предназначена функция ReceiveMessage, которая будет использоваться в примерах. То же самое можно сказать и о функции SendMessage, предназначенной для передачи сообщений.

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

Примечание, относящееся к Win64

В качестве типа переменных, используемых для хранения размера сообщения, выбран тип данных фиксированной точности LONG32, которого будет вполне достаточно для размещения значений параметра размера, включаемого в сообщения при взаимодействии с системами, отличными от Windows, и который годится для возможной последующей перекомпиляции программы для ее использования на платформе Win64 (см. главу 16).

DWORD ReceiveMessage (MESSAGE *pMsg, SOCKET sd) {

 /* Сообщение состоит из 4-байтового поля размера сообщения, за которым следует собственно содержимое. */ 

 DWORD Disconnect = 0;

 LONG32 nRemainRecv, nXfer;

 LPBYTE pBuffer;

 /* Считать сообщение. */

 /* Сначала считывается заголовок, а затем содержимое. */

 nRemainRecv = 4; /* Размер поля заголовка. */

 pBuffer = (LPBYTE)pMsg; /* recv может не передать все запрошенные байты. */

 while (nRemainRecv > 0 && !Disconnect) {

  nXfer = recv(sd, pBuffer, nRemainRecv, 0);

  Disconnect = (nXfer == 0);

  nRemainRecv –=nXfer;

  pBuffer += nXfer;

 }

 /* Считать содержимое сообщения. */

 nRemainRecv = pMsg->RqLen;

 while (nRemainRecv > 0 && !Disconnect) {

  nXfer = recv(sd, pBuffer, nRemainRecv, 0);

  Disconnect = (nXfer == 0);

  nRemainRecv –=nXfer;

  pBuffer += nXfer;

 }

 return Disconnect;

}

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

6.4. Ни в коем случае не reflow!

Из книги Разгони свой сайт автора Мациевский Николай

6.4. Ни в коем случае не reflow! В CSS-движке браузеров существует несколько операций, затрагивающих изменение картинки на экране браузера. В предыдущих тестах было рассмотрено начальное создание документа и способы ускорения это процесса. Однако все вышеприведенные советы в


Получение и пересылка сообщений. Создание ответных сообщений

Из книги Office 2007. Мультимедийный курс автора Мединов Олег

Получение и пересылка сообщений. Создание ответных сообщений Чтобы получить новую почту, выполните команду главного меню Сервис ? Отправить/Получить ? Доставить почту либо нажмите клавишу F9. Все полученные почтовые сообщения будут помещены в папку Входящие и помечены


Пример: очереди сообщений Posix и функция select

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

Пример: очереди сообщений Posix и функция select Дескриптор очереди сообщений (переменная типа mqd_t) не является «обычным» дескриптором и не может использоваться с функциями select и poll (глава 6 [24]). Тем не менее их можно использовать вместе с каналом и функцией mq_notify. (Аналогичный


Реагирование в случае нарушения доверия

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

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


Пример 17-4. Вывод многострочных сообщений с подавлением символов табуляции

Из книги автора

Пример 17-4. Вывод многострочных сообщений с подавлением символов табуляции #!/bin/bash# То же, что и предыдущий сценарий, но...# Символ "-", начинающий строку-ограничитель встроенного документа: <<-# подавляет вывод символов табуляции, которые могут встречаться в теле


Пример 22-1. Простая функция

Из книги автора

Пример 22-1. Простая функция #!/bin/bashfunky (){ echo "Это обычная функция."} # Функция должна быть объявлена раньше, чем ее можно будет использовать. # Вызов функции.funkyexit 0Функция должна быть объявлена раньше, чем ее можно будет использовать. К сожалению, в Bash нет возможности


Пример 22-2. Функция с аргументами

Из книги автора

Пример 22-2. Функция с аргументами #!/bin/bash# Функции и аргументыDEFAULT=default # Значение аргумента по-умолчанию.func2 () { if [ -z "$1" ] # Длина аргумента #1 равна нулю? then echo "-Аргумент #1 имеет нулевую длину.-" # Или аргумент не был передан функции. else echo


Пример: получение семейства адресов сокета

Из книги автора

Пример: получение семейства адресов сокета Функция sockfd_to_family, представленная в листинге 4.4, возвращает семейство адресов сокета.Листинг 4.4. Возвращаемое семейство адресов сокета//lib/sockfd_to_family.c 1 #include "unp.h" 2 int 3 sockfd_to_family(int sockfd) 4 { 5  union { 6   struct sockaddr sa; 7   char data[MAXSOCKADDR]; 8  }


Пример: функция str_echo, использующая стандартный ввод-вывод

Из книги автора

Пример: функция str_echo, использующая стандартный ввод-вывод Сейчас мы модифицируем наш эхо-сервер TCP (см. листинг 5.2) для использования стандартного ввода-вывода вместо функций readline и writen. В листинге 14.6 представлена версия нашей функции str_echo, использующая стандартный


Пример: функция bind и доменный сокет Unix

Из книги автора

Пример: функция bind и доменный сокет Unix Программа, показанная в листинге 15.2, создает доменный сокет Unix, с помощью функции bind связывает с ним полное имя и затем вызывает функцию getsockname и выводит это полное имя.Листинг 15.2. Связывание полного имени с доменным сокетом


Пример: функция mcast_join

Из книги автора

Пример: функция mcast_join В листинге 21.1[1] показана первая часть функции mcast_join. Эта часть демонстрирует простоту интерфейса программирования, не зависящего от протокола.Листинг 21.1. Присоединение к группе: сокет IPv4//lib/mcast_join.c 1 #include "unp.h" 2 #include <net/if.h> 3 int 4 mcast_join(int sockfd, const SA *grp,


Пример: функция mcast_set_loop

Из книги автора

Пример: функция mcast_set_loop В листинге 21.4 показана наша функция mcast_set_loop.Поскольку аргументом является дескриптор сокета, а не структура адреса сокета, мы вызываем нашу функцию sockfd_to_family, чтобы получить семейство адресов сокета. Устанавливается соответствующий параметр