Приемник для протоколов, не требующих соединения

Протоколы, не требующие соединения

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

Приемник

Процесс получения данных на сокете, не требующем соединения, прост. Сначала создают сокет функцией socket или WSASocket. Затем выполняют привязку сокета к интерфейсу, на котором будут принимать данные, функцией bind (как и в случае протоколов, ориентированных на сеансы). Разница в том, что нельзя вызвать listen или accept: вместо этого нужно просто ожидать приема входящих данных. Поскольку в этом случае соединения нет, принимающий сокет может получать дейтаграммы от любой машины в сети. Простейшая функция приема — recvform.

// Code 3.28

int recvfrom(

SOCKET s,

char FAR* buf,

int len,

int flags,

struct sockaddr FAR * from,

int FAR * fromlen

);

Первые четыре параметра такие же, как и для функции recv, включают допустимые значения для flags-. MSG_OOB и MSG_PEEK. Параметр from — структура SOCKADDR для данного протокола слушающего сокета, на размер структуры адреса ссылается fromlen. После возврата вызова структура SOCKADDR будет содержать адрес рабочей станции, которая отправляет данные.

В Winsock 2 применяется другая версия recvform — WSARecvForm:

// Code 3.29

int WSARecvFrom(

SOCKET s,

LPWSABUF lpBuffers,

DWORD dwBufferCount,

LPDWORD lpNumberOfBytesRecvd,

LPDWORD lpFlags,

struct sockaddr FAR * lpFrom,

LPINT lpFromlen,

LPWSAOVERLAPPED lpOverlapped,

LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE

);

Разница между версиями — в использовании структуры WSABUF для получения данных. Можно предоставить один или несколько буферов WSABUF, указав их количество в divBufferCount — в этом случае возможен комплексный ввод-вывод. Суммарное количество считанных байт передается в lpNumberOfBytesRecvd. При вызове функции WSARecvFrom, lpFlags может принимать следующие значения: 0 (при отсутствии параметров), MSG_OOB, MSG_PEEK или MSG_PARTIAL. Данные флаги можно комбинировать логической операцией ИЛИ. Если при вызове функции задан флаг MSG_PARTlAL, поставщик перешлет данные даже в случае приема лишь части сообщения. По возвращении флаг задается в MSG_PARTIAL, только если сообщение принято частично. По возвращении WSARecvFrom присвоит параметру lpFrom (указатель на структуру SOCKADDR) адрес компьютера-отправителя. Опять же lpFromLen указывает на размер структуры SACKADDR, однако в данной функции он является указателем на DWORD. Два последних параметра — lpOverlapped и lpCompletionROUTINE, используются для перекрытого ввода-вывода (см. следующую главу).

Другой способ приема (отправки) данных в сокетах, не требующих соединения, — установление соединения (хоть это и звучит странно). После создания сокета можно вызвать connect или WSAConnect, присвоив параметру SOCKADDR адрес удаленного компьютера, с которым необходимо связаться. Фактически никакого соединения не происходит. Адрес сокета, переданный в функцию соединения, ассоциируется с сокетом, чтобы было можно использовать функции recv и WSARecv вместо recvfrom или WSARecvFrom (поскольку источник данных известен). Если приложению нужно одновременно связываться лишь с одной конечной точкой, можно задействовать возможность подключить сокет дейтаграмм.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: