Книга: Системное программирование в среде Windows

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

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

Часто оказывается удобным отправлять и получать сообщения в виде единых блоков. Как было показано в главе 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;
}

Оглавление книги


Генерация: 1.162. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз