Вход/Регистрация
Системное программирование в среде Windows
вернуться

Харт Джонсон М.

Шрифт:

• Допустимое количество клиентских сокетов ничем не ограничено (функция listen ограничивает лишь количество клиентов, помещаемых в очередь), в то время как количество экземпляров именованных каналов, в зависимости от того, что было указано при первом вызове функции CreateNamedPipe, может быть ограниченным.

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

• Именованные каналы не имеют портов с явно заданными номерами и различаются по именам. 

В случае сервера именованных каналов получение пригодного для работы дескриптора типа HANDLE требует вызова двух функций (CreateNamedPipe и ConnectNamedPipe), тогда как сервер сокета требует вызова четырех функций (socket, bind, listen и accept).

Сравнение клиентов именованных каналов и сокетов

В случае именованных каналов необходимо последовательно вызывать функции WaitNamedPipe и CreateFile. Если же используются сокеты, этот порядок вызовов обращается, поскольку можно считать, что функция socket создает сокет, а функция connect — блокирует.

Дополнительное отличие состоит в том, что функция connect является функцией клиента сокета, в то время как функция ConnectNamedPipe используется сервером именованного канала.

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

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

}

Пример: клиент на основе сокета

Программа 12.1 представляет собой переработанный вариант клиентской программы clientNP (программа 11.2), которая использовалась в случае именованных каналов. Преобразование программы осуществляется самым непосредственным образом и требует лишь некоторых пояснений.

• Вместо обнаружения сервера с помощью почтовых ящиков пользователь вводит IP-адрес сервера в командной строке. Если IP-адрес не указан, используется заданный по умолчанию адрес 127.0.0.1, соответствующий локальной системе.

• Для отправки и приема сообщений применяются функции, например, ReceiveMessage, которые здесь не представлены.

• Номер порта, SERVER_PORT, определен в заголовочном файле ClntSrvr.h.

Хотя код написан для выполнения под управлением Windows, единственная зависимость от Windows связана с использованием вызовов функций, имеющих префикс WSA.

  • Читать дальше
  • 1
  • ...
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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