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

  • HANDLE WSAAsyncGetHostByName( HWND hWnd, unsigned int wMsg, const char FAR * name, char FAR * buf, Int buflen

  • Нумерация lrDA-устройств

  • SOCK_STREAM, 0, NULL

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


    Скачать 2.88 Mb.
    НазваниеЭ. Джонс, Д. Оланд
    АнкорПрограммирование в сетях Windows.pdf
    Дата12.10.2017
    Размер2.88 Mb.
    Формат файлаpdf
    Имя файлаПрограммирование в сетях Windows.pdf
    ТипКнига
    #9346
    страница13 из 50
    1   ...   9   10   11   12   13   14   15   16   ...   50
    // nPortld к сетевому порядку и присвоение результата sm_port.
    InternetAddr.sin_port = htons(nPortld);
    Теперь подготовим сокет для соединения по TCP или UDP.
    Создание сокета
    Создание IP-сокета позволит приложениям осуществлять подключение через
    TCP, UDP и протоколы IP Для открытия IP-сокета при помощи протокола TCP,
    вызовите функцию socket или WSASocket с семейством адресов AFJNET и ти- пом сокета SOCK_STREAM, а также присвойте значение 0 полю протокола s = socket(AF_INET, SOCK_STREAM, 0),
    s = WSASocket(AF_INET, SOCK.STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED),
    Чтобы открыть IP-сокет при помощи протокола UDP, вместо SOCKSTREAM
    укажите тип сокета SOCKDGRAM в функции socket или WSASocket Также мож- но открывать сокет для связи непосредственно по IP — для этого задайте тип сокета SOCK_RAW Подробнее об этом параметре — в главе 13
    Разрешение имен
    Для подключения к узлу по IP Winsock-приложение должно знать IP-адрес этого узла, сложный для запоминания пользователем Большинство людей более охотно обращаются к компьютерам при помощи легко запоминаемых имен узлов, а не IP-адресов В Winsock предусмотрено две функции для раз-
    Решения имени в IP-адрес

    1 2 6 ЧАСТЬ II Интерфейс прикладного программирования Winsock
    Функции gethostbyname и WSAAsyncGetHostByName отыскивают в базе дан- ных узла сведения об узле, соответствующие его имени Обе функции воз- вращают структуру HOSTENT
    struct hostent
    char FAR * h_name,
    char FAR • FAR • h.aliases,
    short h.addrtype,
    short h_length,
    char FAR * FAR * h_addrj.ist,
    Поле hname является официальным именем узла Если в сети использу- ется доменная система имен (Domain Name System, DNS), в качестве имени сервера будет возвращено полное имя домена (Fully Qualified Domain Name,
    FQDN) Если в сети применяется локальный файл узлов (hosts, lmhosts) — это первая запись после IP-адреса Поле h_ahases — массив, завершающийся ну- лем (null-terminated array) дополнительных имен узла Поле b_add? type пред- ставляет возвращаемое семейство адресов Поле hjength охире-црпяег длину в байтах каждого адреса из поля h_addrjist Поле h_addrjist — массив, за- вершающийся 0 и содержащий IP-адреса узла (Узел может иметь несколько
    IP-адресов) Каждый адрес в этом массиве представлен в сетевом порядке
    Обычно приложение использует первый адрес из массива Впрочем, при получении нескольких адресов, приложение должно выбирать адрес случай- ным образом из числа доступных, а не упорно использовать первый
    API-функция gethostbyname определена так struct hostent FAR * gethostbyname (
    const char FAR * name
    Параметр name представляет дружественное имя искомого узла При ус- пешном выполнении функции возвращается указатель на структуру HOSTENT,
    которая хранится в системной памяти Приложение не должно полагать, что эти сведения непременно статичны Поскольку эта память обслуживается си- стемой, оно не должно освобождать возвращенную структуру
    WSAAsyncGetHostByName — асинхронная версия функции gethostbyname,
    оповещающая приложение о завершении своего выполнения с помощью сообщений Windows
    HANDLE WSAAsyncGetHostByName(
    HWND hWnd,
    unsigned int wMsg,
    const char FAR * name,
    char FAR * buf,
    Int buflen
    Параметр hWnd дескриптор окна, которое получит сообщение по за- вершении выполнения асинхронного запроса. Параметр wMsg Windows-

    •ГЛАВА 6 Семейства адресов и разрешение имен '127
    сообщение, которое будет возвращено по завершении выполнения асинх- ронного запроса Параметр пате— дружественное имя искомого узла Па- раметр buf— указатель на область данных, куда помещается HOSTENT Этот буфер должен быть больше структуры HOSTENT и иметь размер, определен- ный BMAXGETHOSTSTRUCT
    Стоит упомянуть еще две функции поиска сведений об узле gethostbyaddr и
    WSAAsyncGetHostByAddr Они полезны, когда вы знаете IP-адрес узла и хотите найти его понятное пользователю имя Функция gethostbyaddr определена так struct HOSTENT FAR • gethostbyaddr(
    const char FAR • addr,
    int len,
    mt type
    ),
    Параметр addr — указатель на IP-адрес в сетевом порядке Параметр len
    задает длину параметра addr в байтах Параметр type должен иметь значение
    AFJNET (IP-адрес) WSAAsyncGetHostByAddr — асинхронная версия функции
    gethostbyaddr
    Номера портов
    Помимо IP-адреса удаленного компьютера для подключения к службе на ло- кальном или удаленном компьютере приложение должно знать номер пор- та службы При использовании TCP и UDP приложение решает, через какой порт связаться Существуют стандартные номера портов, зарезервированные для служб сервера, поддерживающих протоколы более высокого уровня, чем
    TCP Например, порт 21 зарезервирован для FTP, 80 — для HTTP Как уже упо- миналось, стандартные службы обычно используют порты 1-1023 Поэто- му если вы разрабатываете TCP-приложение, которое не использует ни одну из известных служб, старайтесь задействовать порты с номером больше
    1023 Вы можете узнать номера портов, используемых стандартными служ- бами, вызвав функцию getservbyname или WSAAsyncGetServByName Эти фун- кции просто извлекают статическую информацию из файла с именем ser-
    vices В Windows 95 и Windows 98 файл служб расположен в папке %WIN-
    DOWS%, а в Windows NT и Windows 2000 - в %WINDOWS%\System32\Dn- vers\Etc Функция getservbyname определена так
    struct servant
    const
    const
    char
    char
    FAR
    FAR
    FAR
    * getservbyname(
    * name,
    * proto
    Параметр name представляет имя искомой службы Например, если вы пы- таетесь найти порт, используемый FTP, присвойте параметру пате указатель на строку «ftp» Параметр proto иногда ссылается на строку, указывающую прото- кол, под которым зарегистрирована служба из параметра пате Функция WSA-
    •AsyncGetServByName — асинхронная версия getsen b)>name
    В Windows 2000 применен новый динамический метод регистрации и зап- роса информации о службах для TCP и UDP Серверные приложения могут за-

    1 28 ЧАСТЬ II Интерфейс прикладного программирования Winsock регистрировать имя службы, IP-адрес и номер порта службы при помощи функ- ции WSASetSert'ice Клиентские приложения запрашивают информацию об этих службах при помощи комбинации API-функций WSALookupSetviceBegin, WSA-
    LookupServiceNext и WSALookupServtceEnd (см также главу 10)
    Инфракрасные сокеты
    Сокеты инфракрасного канала (Infrared sockets, IrSock) — новая интерес- ная технология, впервые реализованная в Windows СЕ Они позволяют под- ключаться двум компьютерам по инфракрасному последовательному порту
    Инфракрасная связь теперь доступна в Windows 98 и в Windows 2000 Инф- ракрасные сокеты отличаются от традиционных тем, что учитывают непо- стоянство доступности переносных устройств В этой технологии примене- на новая модель разрешения имен
    Адресация
    Поскольку большинство компьютеров с устройствами инфракрасной свя-
    зи (Infrared Data Association, IrDA) мобильны, традиционные схемы разреше- ния имен не эффективны Обычные статические ресурсы, такие как серве- ры имен, бесполезны, когда сетевой клиент перемещается по сети и за ее пределы Для решения этой проблемы IrSock ищет ресурсы в радиусе связи произвольным образом, не налагая нагрузки на всю сеть и не применяя стандартные функции службы имен Winsock или IP-адреса Вместо этого служба имен встроена в поток связи, а для поддержки служб, относящихся к последовательным инфракрасным портам, введено новое семейство адресов
    Структура адреса IrSock содержит имя службы с описанием приложения, ис- пользуемого в вызовах для привязки и подключения, а также идентифика-
    тор устройства (device identifier), определяющий устройство, на котором выполняется данная служба Эта пара аналогична IP-адресу и номеру порта,
    используемым в обычных TCP/IP-сокетах Структура адреса IrSock такова typedef struct sockaddr_irda {
    u_short lrdaAddressFamily,
    u_char irdaDeviceID[4],
    char irdaServiceName[25],
    > SOCKADDR_IRDA,
    Поле lrdaAddressFamily всегда равно AFJRDA Параметр trdaDevicelD
    четырехсимвольная строка, уникально идентифицирующая устройство, на котором запущена определенная служба Это поле игнорируется при созда- нии IrSock-сервера, но важно для клиента, поскольку указывает на IrDA-ycT- ройство, к которому он подключен (В зоне действия может быть несколько устройств ) И, наконец, поле irdaServiceName — это имя службы, которую приложение регистрирует или к которой пытается подключиться
    Разрешение имен
    Адресация может быть основана на селекторах (IrDA Logical Service Access
    Point Selector, LSAP-SEL) или на службах, зарегистрированных Information

    X Л A B A 6 Семейства адресов и разрешение имен '129
    Access Services (IAS) IAS абстрагирует службу от LSAP-SEL в виде дружествен- ного текстового имени, примерно так же, как DNS-сервер отображает име- на компьютеров в цифровые IP-адреса Для успешного соединения вы може- те использовать как LSAP-SEL, так и дружественное пользователю имя, но в последнем случае требуется разрешать имена Как правило, прямой LSAP-SEL-
    «адрес > не применяют, поскольку адресное пространство служб IrDA огра- ничено Реализация Win32 разрешает использовать целые идентификаторы
    LSAP-SEL в диапазоне 1-127 По сути, IAS-сервер можно рассматривать как
    WINS-сервер, поскольку он ассоциирует LSAP-SEL с текстовым именем службы
    Фактически в записи IAS для нас важны лишь три поля имя класса (class name), атрибут (attribute) и значение атрибута (attribute value) Допустим,
    сервер хочет регистрироваться под именем службы MyServer Для этого ему нужно осуществить привязку к соответствующей структуре SOCKADDRJRDA
    Затем добавляется запись IAS с именем класса MyServer, атрибутом IrDATiny-
    ТР LsapSel и значением атрибута, например, 3 Это значение атрибута — сле- дующий неиспользуемый LSAP-SEL, назначенный системой после регистра- ции С другой стороны, клиент передает структуру SOCKADDRJRDA вызову подключения В результате IAS начинает искать службу с именем класса
    MyServer и атрибутом IrDA TinyTP LsapSel Этот IAS-запрос вернет значение 3
    Вы можете сформулировать свой IAS-запрос с помощью параметра IRLMP_
    IAS_QUERYB вызове getsockopt
    Если вы хотите полностью проигнорировать IAS (что не рекомендуется),
    задайте LSAP-SEL-адрес напрямую для имени сервера или конечной точки, с которой хочет соединиться клиент Обходить IAS, требуется только при под- ключении к устаревшим IrDA-устройствам, которые не поддерживают IAS- регистрацию (например, принтерам с инфракрасным портом) Для обхода
    IAS-регистрации и поиска задайте имя службы в структуре SOCKADDRJRDA
    как LSAP-SEL-xxx, где ххх — значение атрибута в диапазоне 1-127 В итоге серверу будет явно назначен данный LSAP-SEL-адрес, а клиент, не ведя IAS- поиск, сразу попытается подключиться к любой службе, выполняемой на
    LSAP-SEL
    Нумерация lrDA-устройств
    Поскольку инфракрасные (ИК) устройства появляются и исчезают из ради- уса связи, необходим метод динамического перечисления соседних уст- ройств Реализация этого механизма в Windows СЕ и в Windows 98/2000 не- скольких отличается В Windows СЕ поддержка IrSock появилась раньше, чем в Windows 98 и Windows 2000, но последние в ответ на запрос нумерации возвращают дополнительную «справочную > информацию Поэтому заголо- вочный файл Af_irda h для Windows СЕ содержит исходные минимальные определения структур, а новые заголовочные файлы других платформ —
    Дополнительные определения для каждой платформы, поддерживающей rbock Для согласованности рекомендуется использовать более поздние вер- сии заголовочного файла Af_irda h
    Нумерация соседних ИК-устройств выполняется функцией getsockopt с параметром IRLMP_ENUMJDEVICES для Структура DEVICEUST передается как

    1 30 ЧАСТЬ II Интерфейс прикладного программирования Winsock параметр optval. Существуют две структуры, одна для Windows 98 и Windows
    2000, а другая — для Windows СЕ. Они определены так:
    typedef struct _WINDOWS_DEVICELIST
    {
    ULONG numDevice;
    WINDOWS_IRDA_DEVICE_INFO Device[1];
    } WINDOWS.DEVICELIST, «PWINDOWS.DEVICELIST, FAR *LPWINDOWS_DEVICELIST;
    typedef struct _WCE_DEVICELIST
    {
    ULONG numDevice;
    WCE_IRDA_DEVICE_INFO Device[1];
    } WCE_DEVICELIST, *PWCE_DEVICELIST;
    Единственное отличие между ними — структура для Windows 98 и Windows
    2000 содержит массив структур WINDOWSJRDAJDEVICEJNFO вместо WCE_
    IRDAJDEVICEJNFO. Условная директива *deflne объявляет DEVICEUST как со- ответствующую структуру, в зависимости от целевой платформы. Аналогич- но, существует и два объявления структуры IRDA_DEVICE_INFO.
    typedef struct _WINDOWS_IRDA_DEVICE_INFO
    {
    u_char irdaDevlceID[4];
    char irdaDevlceName[22];
    u_char irdaOeviceHintsi;
    u_char irdaDeviceHints2;
    u_char irdaCharSet;
    } WINDOWS_IRDA_DEVICE_INFO, *PWINDOWS_IRDA_DEVICE_INFO,
    FAR *LPWINDOWS_IRDA_DEVICE_INFO;
    typedef struct _WCE_IRDA_OEVICE_INFO
    {
    u_char irdaDeviceID[4];
    char irdaDeviceName[22];
    u_char Reserved[2]; . > ^
    } WCE_IRDA_DEVICE_INFO, *PWCE_IRDA_DEVICE_INFO; "
    f
    Условная директива *define объявляет IRDAJDEVICEJNFO, опять-таки, в зависимости от платформы.
    Как мы уже говорили, фактически нумерация ИК-устройств выполняет- ся функцией getsockopt с параметром IRLMP_ENUM_DEVICES. Следующий код перечисляет идентификаторы всех ИК-устройств по соседству.
    SOCKET sock;
    DEVICELIST devList;
    DWORD dwListLen=sizeof(DEVICELIST);
    sock = WSASocket(AF_IRDA, SOCK_STREAM, 0, NULL, 0,
    WSA_FLAG_OVERLAPPED);
    devList.numDevice = 0;

    Г Л А В А 6 Семейства адресов и разрешение имен 131
    dwRet = getsockopt(sock, SOL_IRLMP, IRLMP_ENUMDEVICES,
    (char *)&devList, AdwHstLen);
    Перед тем как структура DEVICELIST будет передана в вызове getsockopt, не забудьте присвоить полю numDevice значение О. При успешной нумерации полю numDevice будет присвоено положительное значение, равное числу структур IRDAJDEVICEJNFO в поле Device. В реальном приложении выпол- нять getsockopt придется неоднократно, чтобы отследить все устройства,
    попавшие в радиус связи. Например, программа должна пытаться обнару- жить ИК-устройство не менее пяти раз. Для этого просто поместите вызов процедуры в цикл с коротким вызовом функции Sleep после каждой безус- пешной нумерации.
    Зная, как нумеровать ИК-устройства, создать клиент или сервер не слож- но. Серверная часть немного проще, поскольку выглядит как «обычный» сер- вер, то есть никаких особых действий не требует. Вкратце порядок действия
    IrSock-сервера таков.
    1. Создание сокета с семейством адресов AFJRDA и типом SOCK_STREAM.
    2. Запись в структуру SOCKADDRJRDA имени службы сервера.
    3. Вызов функции bind с описателем сокета и структурой SOCKADDRJRDA.
    4. Вызов функции listen с описателем сокета и тайм-аутом.
    5. Блокирование вызова функции accept для входящих запросов клиентов.
    Действия клиента сложнее, поскольку необходимо нумеровать ИК-уст- ройства.
    1. Создание сокета с семейством адресов AFJRDA и типом SOCKSTREAM.
    2. Нумерация доступных ИК-устройств путем вызова getsockopt с парамет- ром IRLMP_ENUMJ)EVICES.
    3- Для каждого найденного устройства в структуру SOCKADDRJRDA — за- пись идентификатора найденного устройства, а также имени службы, к которой вы хотите подключиться.
    4. Вызов функции connect с описателем сокета и структурой SOCKADDRJRDA.
    Это действие выполняется для каждой структуры, обработанной на шаге 3-
    Опрос IAS
    Существует два способа определить, запущена ли данная служба на конкрет- ном устройстве. Первый — попытаться подключиться к службе, другой — зап- росить у IAS имя службы. Оба способа требуют нумерации всех ИК-устройств и попыток запросить каждое устройство, пока одно из них не ответит (или подключиться к нему). Запрос выполняется функцией getsockopt с параметром
    IRIMPJAS_QUERY. Указатель на структуру IAS_QUERY передается в параметре
    optval. И снова, существуют две структуры IAS_QUERY: одна — для Windows 98
    и Windows 2000, а другая — для Windows СЕ. Вот их описания.
    typedef struct .WINDOWS.IAS_QUERY
    u_char irdaDeviceID[4]; '* '*'''

    132
    ЧАСТЬ II Интерфейс прикладного программирования Winsock
    char
    char
    u_long
    union
    i rdaClassName[IAS_MAX_CLASSNAME];
    irdaAttribName[IAS_MAX_ATTRIBNAME];
    irdaAttribType;
    LONG irdaAttriblnt;
    struct
    {
    u_long Len;
    u_char OctetSeq[IAS_MAX_OCTET_STRING];
    } irdaAttribOctetSeq;
    struct
    u_long Len;
    u_long CharSet;
    u_char UsrStr[IAS_MAX_USER_STRING];
    } irdaAttribUsrStr;
    } irdaAttribute;
    } WINDOWS_IAS_QUERY, *PWINDOWS_IAS_QUERY,
    FAR «LPWINDOWS.IAS.QUERY;
    typedef struct _WCE_IAS_QUERY
    u_char
    char
    char
    u_short
    union
    irdaDeviceID[4];
    irdaClassName[61];
    irdaAttribName[61];
    irdaAttribType;
    int irdaAttriblnt;
    struct
    int Len;
    u_char 0ctetSeq[1];
    u_char Reserved[3];
    } irdaAttribOctetSeq;
    struct
    iTO HKjJ
    int Len;
    u_char CharSet;
    u_char UsrStr[1];
    u_char Reserved[2];
    } irdaAttribUsrStr;
    1   ...   9   10   11   12   13   14   15   16   ...   50


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