UDP-сокет, присоединившийся к многоадресной группе, не должен "подключаться" к какому-либо адресу с помощью функции connect
или WSAConnect
. Соответственно, для отправки данных такой сокет может использовать только sendto
и WSASendTo
. Сокет, присоединившийся к группе, может отправлять данные на любой адрес, но если используется поддержка качества обслуживания, она работает только при отправке данных на групповой адрес сокета. Отправка данных на групповой адрес не требует присоединения к группе, причем для сокета, отправляющего данные, нет никакой разницы между отправкой данных на обычный адрес и на групповой. И в том и в другом случае используется функция sendto
или WSASendto
(или sendWSASend
с предварительным вызовом connect
). Никаких дополнительных действий для отправки данных на групповой адрес выполнять не требуется. Порт при этом также указывается. Как мы уже видели, номер порта при добавлении сокета в группу не указывается, но сам сокет перед этим должен быть привязан к какому-либо порту. При отправке группового сообщения его получат только те сокеты, входящие в группу, чей порт привязки совпадает с портом, указанным в адресе назначения сообщения.
Если сокет, отправляющий сообщение на групповой адрес, сам является членом этой группы, он, в зависимости от настроек, может получать или не получать свое сообщение. Это определяется его параметром IP_MULTICAST_LOOP
, имеющим тип BOOL
. По умолчанию этот параметр равен True
— это значит, что сокет будет получать свои собственные сообщения. С помощью функции setsockopt
можно изменить значение этого параметра на False
, и тогда сокет не будет принимать свои сообщения.
Параметром IP_MULTICAST_LOOP
следует пользоваться осторожно, т. к. он не поддерживается в Windows NT 4 и требует Windows 2000 или выше. В Windows 9x/МЕ он тоже не поддерживается (хотя упоминания об этом в MSDN нет).
В IP_MULTICAST_TTL
позволяет программе изменить это значение.
У функции WSAJoinLeaf
не предусмотрены параметры для задания адреса сетевого интерфейса, через который следует получать групповые сообщения, поэтому всегда используется интерфейс, выбираемый системой для этих целей по умолчанию. Выбрать интерфейс, который система будет назначать по умолчанию, можно с помощью параметра сокета IP_MULTICAST_IF
. Этот параметр имеет тип TSockAddr
, причем значимыми полями структуры в данном случае являются sin_family
и sin_addr
, а значение поля sin_port
игнорируется.
Значения констант IP_MULTICAST_IF
, IP_MULTICAST_TTL
и IP_MULTICAST_LOOP
также зависят от версии WinSock. В WinSock 1 они должны быть равны 2, и 4, а в WinSock 2–9, 10 и 11 соответственно.
2.2.12. Дополнительные функции
В этом разделе мы рассмотрим некоторые функции, относящиеся в WinSock к дополнительным. В WinSock 1 эти функции вместе со всеми остальными экспортируются библиотекой WSock32.dll, а в WinSock 2 они вынесены в отдельную библиотеку MSWSock.dll (в эту же библиотеку вынесены некоторые устаревшие функции типа EnumProtocols
).
Начнем мы знакомство с этими функциями с функции WSARecvEx
(которая, кстати, является расширенной версией функции recv
, а отнюдь не WSARecv
, как это можно заключить из ее названия), имеющей следующий прототип:
function WSARecvEx(s: TSocket; var buf; len: Integer; var flags: Integer): Integer;
Видно, что она отличается от обычной функции recv
только тем, что флаги передаются через параметр-переменную вместо значения. В функции WSARecvEx
этот параметр не только входной, но и выходной; функция может модифицировать его. Ранее мы познакомились с функцией WSARecv
, которая также может модифицировать переданные ей флаги, но условия, при которых эти две функции модифицируют флаги, различаются.
При использовании TCP (а также любого другого потокового протокола) флаги не изменяются функцией, и результат работы WSARecvEx
эквивалентен результату работы recv
.