Главная страница
Навигация по странице:

  • == INVALID_SOCKET) { printf( socket failed with error Xd\n , WSAGetLastErrorO), return,ZeroMemory(IPXAddr, sizeof(SOCKADDR_IPX))

  • Установка типа IPX-пакета средствами Winsock

  • «define SET_NETBIOS_SOCKADDR(_snb, „type, _name, _port) int _i; (_snb)->snb_family = AF_NETBIOS; (_snb)->snb_type = (_type);

  • (_snb)->snb_name[_i] = *((_name)+_i); } (_snb)->snb_name[NETBIOS_NAME_LENGTH - 1] = (_port);

  • Программирование в сетях Windows. Э. Джонс, Д. Оланд


    Скачать 2.88 Mb.
    НазваниеЭ. Джонс, Д. Оланд
    АнкорПрограммирование в сетях Windows.pdf
    Дата12.10.2017
    Размер2.88 Mb.
    Формат файлаpdf
    Имя файлаПрограммирование в сетях Windows.pdf
    ТипКнига
    #9346
    страница14 из 50
    1   ...   10   11   12   13   14   15   16   17   ...   50
    } irdaAttribute;
    } WCE_IAS_QUERY, *PWCE_IAS_QUERY;
    Как видите, описания одинаковы, кроме длины некоторых символьных массивов.
    Узнать LSAP-SEL-номер определенной службы просто: присвойте полю
    irdaClassName строку свойств для LSAP-SELs: IrDAIrLMP:LsapSel, а полю irda-

    •ГЛАВА 6 Семейства адресов и разрешение имен 133
    AttrtbuteName — имя запрашиваемой службы. Кроме того, укажите в поле
    irdaDevicelD действительный код устройства в радиусе связи.
    Создание сокета
    Поскольку IrSock поддерживает только потоки с установлением соединения,
    чтобы создать ИК-сокет, необходимо указать лишь несколько параметров.
    Зот, например, как создается ИК-сокет с помощью функций socket или WSA-
    Socket. Для Windows СЕ (из-за ограничений Winsock 1.1) используйте функ- цию socket.
    s = socket(AF_IRDA, SOCK_STREAM, 0);
    s = WSASocket(AF_IRDA, SOCK_STREAM, 0, NULL, 0,
    WSA_FLAG_OVERLAPPED);
    Для определенности вы вправе передать 1RDA_PROTO_SOCK_STREAM в ка- честве параметра протокола. Впрочем, он не обязателен, поскольку в ката- логе транспортов есть только одна запись семейства адресов AF_IRDA. Зна- чение AF_IRDA в вызове заставляет по умолчанию использовать эту запись каталога транспортов.
    Параметры сокета
    Большинство 5О_-параметров сокета не применимы к IrDA. поддерживает- ся лишь SO_LINGER. Специфичные для IrSock параметры сокета поддержи- ваются только сокетами семейства адресов AFJRDA. (Они обсуждаются в гла- ве 9, посвященной параметрам сокета и их характеристикам).
    Протоколы IPX/SPX
    Протокол Internetwork Packet Exchange (IPX) используется компьютерами с клиент-серверными сетевыми службами NetWare фирмы Novell. IPX обеспе- чивает связь без установления соединения между двумя процессами, следо- вательно, при передаче пакета рабочей станцией не гарантируется, что он достигнет пункта назначения. Если приложению требуется гарантировать доставку данных, причем именно по протоколу IPX, можно задействовать протокол более высокого уровня.- например, Sequence Packet Exchange (SPX)
    или SPX II, в которых SPX-пакеты передаются при помощи IPX. Winsock по- зволяет приложениям связываться по IPX под управлением Windows 95,
    Windows 98, Windows NT и Windows 2000, но не Windows CE.
    Адресация
    В IPX-сетях сегменты соединяются через IPX-маршрутизаторы. Каждому сег- менту назначается уникальный четырехбайтный номер сети (network num- ber). Эти номера используются IPX-маршрутизатами для управления подклю- чениями между разными сегментами сети. Компьютер, подключенный к сег- менту сети, идентифицируется при помощи шестибайтного номера узла
    (node number) — обычно это физический адрес сетевого адаптера. Узел

    1 34 ЧАСТЬ II Интерфейс прикладного программирования Winsock
    (компьютер) вправе запускать несколько процессов связи по IPX, для разли- чения которых применяются номера сокетов
    Для подготовки Winsock-клиента или сервера к подключению по IPX,
    необходимо настроить структуру SOCKADDRJPX Она определена в заголо- вочном файле Wsipx h, ссылка на него в приложении должна идти вслед за
    Winsock2 h Структура SOCKADDRJPX определена так
    typedef struct sockaddr_ipx
    {
    short sa_family,
    char sa_netnum[4],
    char sa_nodenum[6],
    unsigned short sa_socket,
    } SOCKADDR_IPX, *PSOCKADDR_IPX, FAR *LPSOCKADDR_IPX,
    Поле sajamily всегда равно AF_IPX Поле sajnetnum — 4-байтный номер сети в сегменте IPX-сети Поле sajiodenum — б-байтный номер узла Поле
    sa_socket представляет сокет или порт, используемый для различения IPX- подключений на одном узле
    Создание сокета
    Создать IPX-сокет можно несколькими способами Для открытия 1РХ-соке- та вызовите функции socket или WSASocket с семейством адресов AFJPX, ти- пом сокета SOCKJDGRAM и протоколом NSPROTOJPX
    s = socket(AF_IPX, SOCK.DGRAM, NSPROTO.IPX),
    s = WSASocket(AF_IPX, SOCK.DGRAM, NSPROTO_IPX,
    NULL, 0, WSA_FLAG_OVERLAPPED),
    Заметьте, что третий параметр протокола должен быть обязательно задан и не равен 0 Это важно, поскольку поле протокола может использоваться для настройки особых типов IPX-пакетов
    Как мы уже говорили, IPX обеспечивает ненадежное соединение без дей- таграмм Если приложению требуется надежное соединение с применени- ем этого протокола, оно может использовать поверх IPX протоколы более высокого уровня, такие как SPX и SPX II Для этого необходимо при вызове функций socket или WSASocket задать соответствующие значения полей типа — SOCK_SEQPACKET или SOCKJTREAM, и протокола — NSPROTO_SPX
    или NSPROTOJPXII
    Если тип сокета — SOCKJSTREAM, данные передаются в виде непрерывно- го потока байт, без разделения сообщений, подобно действию сокета в TCP/
    IP Если тип сокета — SOCK_SEQPACKET, данные передаются с разделителя- ми сообщений Например, передатчик отправляет 2000 байт — приемник не сможет ответить, пока не получит все 2000 байт В SPX и SPXII для этого нуж- но указать бит конца сообщения в заголовке SPX Для сокетов типа SOCK_
    SEQPACKET подразумевается, что этот бит указан, и выполнение Winsock- функции recv и WSARecv не завершится, пока пакет не будет получен Для поточных сокетов бит конца сообщения не требуется, и выполнение функ- ции recv будет завершено сразу же по получении любых данных, независи-
    I

    Г Л А В А 6 Семейства адресов и разрешение имен '135
    мо от наличия бита конца сообщения С точки зрения отправителя при ис- пользовании типа SOCK_SEQPACKET сообщения размером меньше пакета,
    всегда передаются с указанным битом конца При отправке нескольких па- кетов этот бит задается только в последнем пакете
    Привязка сокета
    Когда IPX-приложение при помощи функции bind создаст привязку локаль- ного адреса к сокету, указывать номер сети и адрес узла в структуре SOCKA-
    DDR IPX не нужно Функция bind заполнит эти поля при помощи первого же сетевого интерфейса IPX, доступного в системе Если на компьютере ус- тановлено несколько сетевых адаптеров, привязка к конкретному интерфей- су также не требуется В Windows 95, Windows 98, Windows NT и Windows
    2000 реализована виртуальная внутренняя сеть, в которой к каждому сете вому адаптеру можно обратиться, независимо от того, к какой физической сети он подключен (Внутренние номера сети подробно рассмотрены далее в этой главе ) После успешной привязки приложения к локальному интер- фейсу с помощью функции getsockname вы можете узнать номер локальной сети и номер узла следующим образом
    SOCKET sdServer,
    SOCKADOR.IPX IPXAddr,
    int addrlen = sizeof(SOCKADDR_IPX),
    if ((sdServer = socket (AF_IPX, SOCK_DGRAM, NSPROTO.IPX))
    == INVALID_SOCKET)
    {
    printf( socket failed with error Xd\n ,
    WSAGetLastErrorO),
    return,
    ZeroMemory(&IPXAddr, sizeof(SOCKADDR_IPX)),
    IPXAddr sa_family = AF_IPX,
    IPXAddr sa_socket = htons(5150),
    if (bind(sdServer, (PSOCKADDR) «JPXAddr, sizeof(SOCKADDR_IPX))
    == SOCKET_ERROR)
    {
    pnntf( bind failed with error Xd\n ,
    WSAGetLastErrorO),
    return,
    (getsockname((unsigned) sdServer, (PSOCKADDR) &IPXAddr, &addrlen)
    == SOCKET_ERR0R)
    pnntf( getsockname failed with error Xd
    1
    , * '
    WSAGetLastErrorO),
    return,

    136
    ЧАСТЬ II Интерфейс прикладного программирования Winsock
    // Вывод информации SOCKADDR_IPX, возвращенной getsockname()
    Внутренний номер сети
    В IPX номер сети (внутренний или внешний) определяет сегменты сети и применяется для маршрутизации IPX-пакетов между сегментами В Windows
    95, Windows 98, Windows NT и Windows 2000 предусмотрен внутренний но- мер сети, используемый для внутренней маршрутизации и четкой иденти- фикации компьютера при межсетевых подключениях (несколько сетей, со- единенных мостами) Внутренний номер сети также называется виртуаль- ным, поскольку определяет еще один (виртуальный) сегмент межсетевого соединения Таким образом, при настройке внутреннего номера сети для компьютеров под управлением Windows 95, Windows 98, Windows NT или
    Windows 2000 сервер NetWare или IPX-маршрутизатор добавят дополнитель- ный транзит (hop) в маршрут к этому компьютеру
    На компьютере с несколькими сетевыми адаптерами внутренняя виртуаль- ная сеть выполняет специальную задачу Для привязки к локальному сетевому интерфейсу приложению не надо указывать информацию о локальном интер- фейсе достаточно присвоить значение 0 полям sajnetnum и sanodenum струк- туры SOCKADDRJPX Дело в том, что IPX может маршрутизировать пакеты из любой внешней сети к любому локальному сетевому интерфейсу при помощи внутреннего номера сети Даже если приложение явно привязано к сетевому интерфейсу в сети А, а пакет пришел по сети В, внутренний номер сети все-таки позволит передать его приложению
    Установка типа IPX-пакета средствами Winsock
    Выбрать тип IPX-пакета можно при создании сокета, задав параметр NSP-
    ROTOJPX Поле типа пакета в IPX-пакете указывает тип службы, предложен- ной или запрошенной IPX-пакетом Фирмой Novell определены следующие типы пакетов
    Ш Olh — Routing Information Protocol (RIP),
    Ш 04h — Service Advertising Protocol (SAP),
    Ш 05h — Sequenced Packet Exchange (SPX),
    M l l h — NetWare Core Protocol (NCP),
    14h — широковещательный пакет для Novell NetBIOS
    Чтобы изменить типа IPX-пакета, достаточно просто указать NSPROTO_
    IPX+ п в качестве параметра протокола в функции socket, где п — номер типа пакета Например, для открытия IPX-сокета с типом пакета 04h (SAP), вызо- вите socket так
    s = socket(AF_IPX, SOCK.DGRAM, NSPROTO_IPX + 0x04);

    СЛАВА 6 Семейства адресов и разрешение имен 137
    разрешение имен jpX-адресация в Winsock довольно неудобна, поскольку для формирования ад- реса нужно предоставить многобайтовые номера сети и узла Впрочем, IPX по- зволяет приложениям обнаруживать службы путем использования дружествен- ных имен для получения номера сети, узла и порта по протоколу SAP Winsock 2
    предоставляет независимый от протокола способ регистрации имен функци- ей WSASetService (подробней — в главе 10) По протоколу SAP IPX-сервер может задействовать эту функцию для регистрации под дружественным именем но- меров сети, узла и порта, которые слушает Winsock 2 также предоставляет не- зависимый от протокола способ разрешения имен с помощью функций WSA-
    lookupServiceBegin, WSALookupServtceNext и WSALookupServiceEnd
    Можно выполнить свою собственную регистрацию <имя — служба > и ве- сти поиск, открыв IPX-сокет и выбрав тип SAP пакета После открытия со- кета вы вправе начать широковещание SAP-пакетов в IPX-сети для регистра- ции и обнаружения в ней служб Но для этого необходимо хорошо знать протокол SAP и уметь программно декодировать SAP-пакет IPX
    Протоколы NetBIOS
    Этот интерфейс уже рассматривался в главе 1, поэтому обсуждаемый здесь материал покажется вам знакомым Для адресации NetBIOS из Winsock не- обходимо знать имена NetBIOS и номера LANA Здесь мы уделим основное внимание особенностям доступа к NetBIOS из Winsock
    ПРИМЕЧАНИЕ Семейство адресов NetBIOS доступно в Winsock толь- ко под управлением Windows NT и Windows 2000 Па платформах
    Windows 9x и Windows СЕ оно недоступно
    Адресация
    Адресация компьютеров в 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.

    Г Л А В А 6 Семейства адресов и разрешение имен »139
    Создание сокета
    При создании 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 (но не оба одновременно). Третий пара-
    M e T
    p j
    _ 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

    1 40 ЧАСТЬ II Интерфейс прикладного программирования Winsock
    В данном псевдокоде все доступные протоколы сначала нумеруются, а за- тем в цикле выявляются те, которые относятся к семейству адресов AF^NET-
    BIOS. Затем идет поиск сокетов с типом SOCK_SEQPACKET. Если бы мы хоте- ли передавать дейтаграммы, следовало бы искать сокеты с типом SOCKJDG-
    RAM. Когда тип сокета совпадет с желаемым — найден доступный для исполь- зования транспорт NetBIOS. Если нужен помер LANA, возьмите абсолютное значение поля iProtocol структуры WSAPROTOCOLINFO Единственное ис- ключение — номер 0. Поле iProtocol для этого LANA равно 0x80000000, так как номер 0 зарезервирован для Winsock. Количество действительных транс- портов содержится в переменной/
    Протокол AppleTalk
    Winsock поддерживает AppleTalk уже давно, хотя знают об этом немногие.
    Вероятнее всего, вы не захотите использовать протокол AppleTalk, если толь- ко вам не нужно соединяться с компьютерами Macintosh. AppleTalk похож на
    NetBIOS: сервер динамически регистрирует определенное имя, по которо- му с ним могут соединяться клиенты. Впрочем, имена AppleTalk значитель- но сложнее имен NetBIOS
    1   ...   10   11   12   13   14   15   16   17   ...   50


    написать администратору сайта