double arrow

Создание сокетов и адресации для NetBIOS

Адресация компьютеров в NetBIOS основана на именах NetBIOS Напомним,что имя NetBIOS состоит из 16 символов, причем последний обозначает тип службы, к которой относится это имя Имена NetBIOS бывают уникальными и групповыми Уникальное имя может использоват ься только одним процес-сом в сети Например, если сеансовый сервер зарегистрируется под именем FOO, то для соединения с ним клиенты будут использовать это имя. Под групповым именем может зарегистрироваться группа приложений — тогда направляемые на это имя дейтаграммы получат все зарегистрировавшие его процессы

Структура адресации NetBIOS в Wmsock определена в файле Wsnetbs h

«define NETBIOS_NAME_LENGTH 16

struct sockaddr nb

short snb_family,

u

_short snb_type,

1 38 ЧАСТЬ II Интерфейс прикладного программирования Winsock

char snb_name[NETBIOS_NAME_LENGTH];

} SOCKADDR_NB, «PSOCKADDRJJB, FAR «LPSOCKADDRJIB;

Поле snbjamily задает семейство адресов этой структуры, поэтому оно

всегда должно быть равно AFJVETBIOS. В поле snbjype указывается тип име-ни: уникальное или групповое. Для этого поля можно использовать следую-щие определения:

«define NETBIOSJJNIQUE.NAME (0x0000)

«define NETBIOS_GROUP_NAME (0x0001)

Наконец, в поле snbjiame содержится собственно имя NetBIOS.

Зная, что означает каждое поле и чему оно должно быть равно, вы може-те разобраться в следующем полезном макросе, который определен в заго-ловочном файле и задает нужные значения полям данной структуры:

«define SET_NETBIOS_SOCKADDR(_snb, „type, _name, _port)

int _i;

(_snb)->snb_family = AF_NETBIOS;

(_snb)->snb_type = (_type);

for (_i = 0; _i < NETBIOS_NAME_LENGTH - 1;

(_snb)->snb_name[_i] = ' ';

}

for (_i =0;

•((.name) + _i)!= '\0'

&& _i < NETBIOS_NAME_LENGTH - 1;

(_snb)->snb_name[_i] = *((_name)+_i);

}

(_snb)->snb_name[NETBIOS_NAME_LENGTH - 1] = (_port);

Первый параметр макроса — _snb, адрес заполняемой вами структуры

SOCKADDRNB. Как видите, полю snbjamily автоматически присваивается

значение AFJVETBIOS. Для параметра Jype задайте значение NETBIOSJJNI-QUE_NAME или NETBIOS_GROUPJSfAME. Параметр jiame - это имя NetBIOS;

предполагается, что оно состоит либо из NETBIOSJ4AMEJENGTH - 1 сим-волов, либо содержит меньшее число символов и является строкой с 0 в кон-це. Заметьте, что поле snbname сначала заполняется пробелами, а в конце макроса 1б-й символ строки snbjiame получает значение jport.

Как видите, определить структуру имени NetBIOS в Winsock достаточно просто. В отличие от TCP и IrDA, разрешение имени в NetBIOS скрыто от вас, поэтому не нужно сопоставлять имени физический адрес перед началом работы. Дело в том, что NetBIOS использует несколько протоколов в каче-стве протоколов нижнего уровня, и каждый из них имеет собственную схе-му адресации. В следующем разделе мы приведем пример простого клиент-серверного приложения, использующего интерфейс NetBIOS в Winsock.

Создание сокета

При создании NetBIOS-сокета очень важно верно задать номер LANA. Как и для собственного API NetBIOS, нужно знать, какие номера LANA доступны приложению. Помните, что клиент и сервер NetBIOS должны использовать общий транспортный протокол для прослушивания и соединения. Суще-ствует два способа создания сокета NetBIOS. Первый — вызвать функцию socket или WSASocket:

s = WSASocket(AF_NETBIOS, SOCK.DGRAM | SOCK.SEQPACKET, -lana,

NULL, 0, WSA_FLAG_OVERLAPPED);

Чтобы использовать дейтаграммный сокет, назначте параметру type функ-ции WSASocket значение SOCK_DGRAM, а сокету с установлением соединения значение SOCK_SEQPACKET (но не оба одновременно). Третий параметр pj protocol, номер LANA, на котором нужно создать сокет (он должен быть отрицательным). Значение четвертого параметра — NULL, так как вы задаете свои собственные параметры, не используя структуру WSAPROTO-COL_ INFO. Пятый параметр не используется. Наконец, параметр dwFlags ра-вен WSAFIAG OVERLAPPED. Это значение следует использовать при всех об-ращениях к функции WSASocket.

Недостаток этого способа создания сокетов в том, что вы должны знать доступные номера LANA. К сожалению, в Winsock не существует простого способа нумерации LANA. Конечно, для выяснения свободных номеров LANA можно использовать функцию Netbios с параметром NCBENUM. Но Winsock предлагает альтернативу — перечисление всех транспортных протоколов с помощью функции WSAEnumProtocols (см. главу 5). В следующем примере перечисляются все транспортные протоколы, обнаруживаются транспорты NetBIOS и создаются сокеты для каждого из них.

dwNum = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);

if (dwNum == SOCKET_ERROR)

{

// Ошибка

}

for (i = 0; i < dwNum; i++)

{

// Поиск записей в семействе адресов AF_NETBIOS

if (lpProtocolBuf[i].iAddressFamily == AF_NETBIOS)

{

// поиск сокетов с типом SOCK_SEQPACKET или SOCK_DGRAM

if (lpProtocolBuf[i].iSocketType == SOCK.SEQPACKET)

{

= WSASocket(FROM_PROTOCOL_INFO,

FROM_PROTOCOL_INFO, FROM_PROTOC0L_INF0,

&lpProtocolBuf[i], 0, WSA_FLAG OVERLAPPED);

av

В данном псевдокоде все доступные протоколы сначала нумеруются, а за-тем в цикле выявляются те, которые относятся к семейству адресов AF^NET-BIOS. Затем идет поиск сокетов с типом SOCK_SEQPACKET. Если бы мы хоте-ли передавать дейтаграммы, следовало бы искать сокеты с типом SOCKJDG-RAM. Когда тип сокета совпадет с желаемым — найден доступный для исполь-зования транспорт NetBIOS. Если нужен помер LANA, возьмите абсолютное значение поля iProtocol структуры WSAPROTOCOLINFO Единственное ис-ключение — номер 0. Поле iProtocol для этого LANA равно 0x80000000, так как номер 0 зарезервирован для Winsock. Количество действительных транс-портов содержится в переменной.


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



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