Книга: Системное программирование в среде 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;
}
- Сокеты Windows
- Серверные функции сокета
- Клиентские функции сокета
- Сравнение именованных каналов и сокетов
- Пример: функция приема сообщений в случае сокета
- Пример: клиент на основе сокета
- Пример: усовершенствованный сервер на основе сокетов
- Внутрипроцессные серверы
- Ориентированные на строки сообщения, точкив хода DLL и TLS
- Пример: безопасная многопоточная DLL для обмена сообщениями через сокет
- Пример: альтернативная стратегия создания безопасных библиотек DLL с много поточной поддержкой
- Дейтаграммы
- Сравнение Berkeley Sockets и Windows Sockets
- Перекрывающийся ввод/вывод с использованием Windows Sockets
- Windows Sockets 2
- Резюме
- Упражнения
- Пример установочного скрипта
- Пример из практики
- 2.1.3. Функция getopt_long()
- ПРИМЕР ПРОСТОЙ ПРОГРАММЫ НА ЯЗЫКЕ СИ
- Группировка по встроенным функциям и UDF
- Примеры получения статистики
- Пример применения метода «пять почему»
- Пример 12-8. Частота встречаемости отдельных слов
- 19.1.1. Функция jQuery()
- 1.2.5. Пример программы
- Пример 17-10. Блочный комментарий
- Примеры