Адресация компьютеров в 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. Количество действительных транс-портов содержится в переменной.