ГЛАВА 15 Элемент управления Winsock
497
Чистинг 15-3. (продолжение)
Timer1.Enabled = True
cmdConnect.Enabled = True
cmdListen.Enabled = True
I cmdDisconnect.Enabled = False
II
cmdSendData. Enabled = False
c
cmdCloseListen.Enabled = False
lblLocallP.Caption = WinSocki.LocallP
End Sub
Private Sub optIRDA_Click()
' Задайте тип сокета как IrDA
К
1
optlRDA.Value = True
SocketType = 2
End Sub
ЫЩ
eeoXO
Private Sub optTCP_Click()
1
Задайте тип сокета как TCP
optTCP.Value = True
SocketType = 0
cmdConnect.Caption = "Connect"
End Sub
Private Sub Timer1_Timer()
' Это - событие, вызываемое при срабатывании таймера.
' Обновляем надпись информацией о состоянии сокета
Select Case WinSocki.State
Case 0
lblState.Caption = "sckClosed"
Case 1
lblState.Caption = "sckOpen"
Case 2
lblState.Caption = "sckListening"
Case 3
lblState.Caption = "sckConnectionPending"
Case 4
lblState.Caption = "sckResolvingHost"
Case 5
lblState.Caption = "sckHostResolved"
Case 6
lblState.Caption = "sckConnecting"
Case 7
lblState.Caption = "sckConnected"
di.
•Щ
см. след. стр.
498
ЧАСТЬ II Интерфейс прикладного программирования Wlntock
Листинг 15-3.
(продолжение)
sckClosing"
ШНУОНТ
Case 8
lblState.Caption
Case 9
lblState.Caption = "sckError"
End Select
End Sub
Private Sub WinSock1_Close()
' Другая сторона инициировала закрытие соединения,
' и мы также закрываем соединение со своей стороны.
' Верните кнопкам начальное состояние
T • • xi.
да
WinSocki.Close cmdConnect.Enabled = True cmdListen.Enabled = True cmdDisconnect.Enabled = False cmdSendData.Enabled = False cmdCloseListen.Enabled = False
End Sub
Private Sub WinSock1_ConnectionRequest()
' Мы получили запрос клиента на соединение; принимаем его ' на прослушивающем сокете
WinSocki.Accept
End Sub {)i( -
Private Sub WinSock1_DataArrival(ByVal bytesTotal) i
1
Это - событие, извещающее о поступлении данных.
' Получаем данные и добавляем их в список. }eJ8.t
Dim rdata
- ore
4 S
:•»№
WinSocki.GetData rdata
Listi.Addltem rdata
E n d sub ,
Private Sub WinSock1_Error(ByVal number, ByVal description)
Произошла ошибка; выводим сообщение и закрываем сокет
MsgBox description ,
Call WinSock1_Close ).«ц
End Sub з
Мы не станем углубляться в специфику кода, поскольку он аналогичен коду приложения SockTCP из листинга 15-2. Единственное отличие — два обсуждавшихся ограничения. Как видите, элемент управления Windows СЕ
Г Л А В А 15 Элемент управления Winsock 499
Winsock является достаточно «сырым», он не отработан в такой степени, как версия Winsock для настольных компьютеров. Библиотеки типов реализо- ваны не полностью: вы должны отличать тип протокола, используя простое целочисленное значение, а не перечислимый тип. Кроме того, существует проблема с состоянием сокета (о ней — чуть позже).
Обработка инфракрасных (ИК) соединений не сильно отличается от об- работки TCP-подключений. Единственное различие — когда прослушиваю- щий сокет устанавливается на ИК-порту. ИК-сервер известен по его имени службы (подробней — в главе 6). У элемента управления Winsock имеется дополнительное свойство
ServiceName. Ему можно задать значение из тексто- вого поля, используя которое клиенты пытаются установить соединение
Например, следующий код переводит элемент управления Windows CE Win- sock с именем
CeWinsock в прослушивающий режим MyServer.
CeWinsock.Protocol = 2 ' протокол 2 - IrSockCeWinsock.ServiceName = "MyServer"CeWinsock.ListenДругих требований к публикации службы с использованием ИК-сокетов нет. Вам необходимо указать лишь имя службы.
Проблема с элементом управления VBCE WinsockНе совсем понятно использование перечислимых значений для состояний
Winsock. По какой-то странной причине эти значения определяются в среде разработки, однако при
использовании перечислимого типа sck в коде на уда- ленных устройствах постоянно вьщается сообщение An error was encountered while running this program. Если заменить перечислимые типы соответствующи- ми числовыми эквивалентами, ошибка исчезает. Это считается неполадкой и будет исправлено в последующих версиях комплекта разработчика.
РезюмеЭлемент управления Winsock, поставляемый с Visual Basic, полезен в про- стых, некритичных приложениях, которым необходимы функции работы с сетью. Некоторые проблемы в версии Winsock, поставлявшейся с Visual Basic 5.0,
затрудняют использование элемента управления в приложениях. В после- дней версии Visual Basic все они устранены. Winsock позволяет добавить в приложение Visual Basic простые функции работы с сетью. Конечно, возмож- ности элемента управления ограничены, и для приложений, которым тре- буется интенсивно взаимодействовать с Winsock, лучше вручную импорти- ровать все функции и константы из DLL-библиотеки Winsock. Как уже упо- миналось, во второй части книги приведены примеры на Visual Basic, импор- тирующие функции Winsock из библиотеки Ws2_32.dll. Эти приложения —
SimpleTCP и SimpleUDP расположены на прилагаемом компакт-диске, как и соответствующие файлы Winsock.bas.
Ч А С Т Ь I I I
СЛУЖБА
УДАЛЕННОГО
ДОСТУПА (RAS)
UK
I JO.
Мы уже описали все доступные в Microsoft Windows сетевые API-функции,
которые позволяют разрабатывать приложения, способные взаимодейство- вать с другими приложениями по сети. В большинстве случаев наши иссле- дования фокусировались на приложении и уровнях представления данных семиуровневой модели OSI. Мы не обсуждали детали отдельных сетевых про- токолов и в основном рассматривали использование функций, независимо от протокола.
Последняя часть книги посвящена службе удаленного доступа (Remote
Access Service, RAS), позволяющей пользователям подключаться к локальной сети с удаленного компьютера и использовать сетевые функции, как если бы они были подключены к удаленной сети напрямую.
Л А В А 1 6Клиент службы RAS
Все платформы Microsoft Windows используют клиент RAS, позволяющий подключаться к удаленному компьютеру, если тот является сервером удален- ного доступа. Обычно клиент RAS задействует для этого модем, который подсоединяется к телефонной линии и вызывает удаленный компьютер пу- тем набора номера. Из-за этого клиент RAS иногда называют
клиентам уда-ленного доступа (dial-up networking, DUN).
Сервер должен находиться в режиме ожидания вашего DUN-подключе- ния. Клиент RAS может устанавливать соединение с несколькими типами серверов удаленного доступа. Для этого он пользуется стандартными про- мышленными
кадрирующими (framing) протоколами, которые могут пере- давать следующие протоколы связи.-
Ш Point-to-Point Protocol (PPP) - IP, IPX и NetBEUI;
•
Serial Line Internet Protocol (SLIP) — только IP;
•
Asynchronous NetBEUI (Microsoft Windows NT 3.1, Microsoft Win-dows for Workgroups 3-11) — только NetBEUI.
Кадрирующие протоколы описывают процесс передачи данных через
RAS-соединение и указывают, какой протокол сетевого соединения (типа
TCP/IP или IPX) может устанавливать связь через подключение. Если сервер поддерживает
один из перечисленных кадрирующих протоколов, то клиент может установить соединение. В Windows 95, 98, 2000 и NT предусмотрен компонент сервера RAS, поддерживающий все указанные кадрирущие про- токолы.
Если было установлено соединение между RAS-клиентом и сервером, то стеки сетевого протокола (в зависимости от используемого кадрирующего протокола) могут взаимодействовать через подключение RAS с удаленным компьютером, как если бы компьютеры были соединены в рамках ЛВС. Ес- тественно, пропускная способность многих модемов сегодня значительно ниже прямого соединения ЛВС.
Когда сервер RAS принимает соединение по телефонной линии, то сна- чала он устанавливает соединение с клиентом с помощью одного из кадри- рующих протоколов. Если кадрирующий протокол определен, то сервер де- лает попытку аутентифицировать пользователя, устанавливающего соедине- ние. API-функции RAS позволяют клиенту задать имя пользователя, пароль и домен, проверяющий учетные реквизиты на сервере. Когда RAS-сервер
Windows 2000 или Windows NT получает эту информацию, он подтвержда-
5 0 2 ЧАСТЬ III Служба удаленного доступа (RAS)
* ет учетные реквизиты, применяя доменные механизмы безопасности досту- па. При этом сервер RAS не подключает клиента к домену Windows NT, а про- веряет с помощью реквизитов права пользователя на подключение.
Процесс подключения RAS не то же самое, что процесс входа в домен
Windows NT, но после успешного соединения удаленный компьютер может войти в домен Windows NT. В этой главе вы не найдете описания процесса подключения к домену. В Windows 95 и Windows 98 служба RAS способна ав- томатически произвести вход в домен от имени компьютера после аутенти- фикации удаленного соединения через телефонный справочник.
Для установки и управления устройствами связи, такими как модемы, ис- пользуется
программный интерфейс компьютерной телефонии (Telephony
Application Programming Interface, TAPI). Он управляет аппаратными пара- метрами этих устройств. Когда вы устанавливаете RAS-соединение с помо- щью модема, TAPI включает модем и посылает ему информацию о набирае- мом номере. В результате RAS рассматривает модемы просто как модемные порты TAPI-интерфейса, которые могут набирать номер и устанавливать телефонное соединение с удаленным сервером. Некоторые из API-функций
RAS ссылаются на модемные порты TAPI-интерфейса, когда вы запрашивае- те информацию о RAS-соединении.
В этой главе мы расскажем, как программно использовать RAS для уста- новления соединений с удаленной сетью. Начнем с описания файлов заго- ловков и библиотек, необходимых для создания приложения. Затем будут описаны основы соединений через телефонную линию — как фактически устанавливается удаленное соединение. Далее мы рассмотрим настройку за- писей телефонного справочника RAS для определения детальных свойств
RAS-соединения. И наконец, поговорим о том, как управлять уже установлен- ным соединением.
Компиляция и компоновкаПри разработке приложения RAS нужно подключить файлы заголовков и библиотек:
•
Ras.h —
содержит прототипы функций и структуры данных, используе- мые API-функциями RAS;
•
Raserror.h — содержит заданные коды ошибок, возвращаемые API-функ- циями RAS при сбоях;
И
Rasapi32.1ib — библиотека всех API-функций RAS.
В файле Raserror.h вы найдете строку описания ошибки для каждого кода,
используемого в RAS. Функция
RasGetErrorString позволяет программно отыс- кивать строки с описанием ошибки, ассоциируемые с конкретным кодом:
DWORD RasGetErrorString(UINT uErrorValue,LPTSTR lpszErrorString,DWORD cBufSize Г Л А В А 16 Клиент службы RAS 503
Параметр
uErrorValue получает конкретное значение кода ошибки RAS
возвращаемое RAS-функцией. Параметр
ipszErrorString — это предоставляе- мый приложением буфер, куда будет занесено описание ошибки с кодом из
uErrorValue. Буфер для хранения этой строки нужно сделать достаточно большим — не менее 256 символов. Иначе процедура вернет ошибку
ER-ROR_INSUFFICIENT_BUFFER. Последний параметр —
cBufSize, содержит раз- мер буфера, который вы задали в
IpszErrorString.Структуры данных и вопросы совместимостиплатформИспользуемые RAS-функциями структуры данных имеют дополнительные поля данных: включенные или нет — зависит от значения
WINVER. В структу- ре данных RAS также есть поле
dwSize, в котором необходимо задать размер используемой вами RAS-структуры в байтах. Это влияет на работу RAS-функ- ций, использующих эти структуры, так как они настроены на конкретную платформу. Правила
WINVER применимы для платформ Windows 95,98, 2000
и NT, но не для Windows CE (Windows CE SDK не определяет
WINVER). Следу- ющие параметры указывают, что приложение RAS настроено под:
•
WINVER = 0x400 -Windows 95, 98 или NT 4;
щнШ WINVER = 0x401 — Windows NT 4; 1.
• WINVER = 0x500 - Windows 2000.
П" •ЗйОШГхЗ.Ша
Служба RAS не рассчитана на использование единственного исполняемо- го файла, запускающегося на всех платформах. Теоретически, при аккуратном программировании можно обеспечить работу приложения на всех платфор- мах (конечно, исключая Windows CE). Но мы все же рекомендуем конструи- ровать RAS-приложение для конкретной платформы.
Обновление DUN 1.3 и Windows 95Между исходной версией и OSR 2 было выпущено еще несколько версий
Windows 95. OSR 2 не была конечным продуктом, напротив, она устанавли- валась только на новые OEM-компьютеры. У каждой версии свои особенно- сти работы API-функций RAS, поэтому рекомендуется установить последний пакет обновления RAS — DUN 1.3, загрузив его со страницы
http://www.mic-rosoft.com/support. Но мы предполагаем, что вы это уже сделали, и не будем обсуждать RAS из предыдущих версий DUN.
Функция RasDialДля подключения к удаленному компьютеру RAS-приложение
клиента вызы- вает функцию RasDial. Это довольно сложная функция с множеством пара- метров вызова, используемых для набора номера, аутентификации и уста- новления соединения с удаленным сервером.
RasDial определяется следую- щим образом:
5 0 4 Ч А С Т Ь III Служба удаленного доступа (RAS)DWORD RasDiaKLPRASDIALEXTENSIONS lpRasDialExtensions,LPCTSTR lpszPhonebook,LPRASDIALPARAMS lpRasDialParams,DWORD dwNotifierType,LPVOID lpvNotifier,LPHRASCONN lphRasConn);Параметр
ipRasDialExtensions — необязательный указатель на структуру
RASDIALEXTENSIONS, которая позволяет приложению активизировать расши- ренные возможности для
RasDial В Windows 95, 98 и СЕ этот параметр иг- норируется и должен иметь значение
NULL Структура
RASDIALEXTENSIONSопределена так
typedef struct tagRASDIALEXTENSIONS {DWORD dwSize, IDWORD dwfOptions,HWND hwndParent; iULONG_PTR reserved;#if (WINVER >= 0x500)ULONG_PTR reserved"!,RASEAPINFO RasEapInfo,«endif} RASDIALEXTENSIONS,Как мы и говорили, размер этой структуры на этапе компиляции зависит от значения
WINVER Ее поля описываются следующим образом
•
dwSize — должен содержать размер (в байтах) структуры
RASDIALEX-TENSIONSШ dwfOptions — позволяет задавать для использования расширений
Ras-Dial следующие битовые флаги
8
RDEOPTJJsePreftxSuffix — задает для
RasDial использование префикса и суффикса, ассоциированных с конкретным устройством набора номера,
И
RDEOPT PausedStates — дает возможность
RasDial использовать режим паузы, позволяя пользователям производить повторный вход в систе- му, изменять пароли и задавать номер обратного вызова,
Ш RDEOPT JgnoreModemSpeaker —
RasDial игнорирует параметры дина- мика модема в телефонном справочнике RAS,
И
RDEOPT_SetModemSpeaker — включает динамик модема, если задан
RDEOPT JgnoreModemSpeaker,Ш RDEOPTJgnoreSoftwareCompression —
RasDial игнорирует параметры программного сжатия,
И
RDEOPT_SetSoftwareCompression — включает программное сжатие, если задан
RDEOPTJgnoreSoftwareCompression,Ш RDEOPT_PauseOnScnpt — предназначен для внутреннего использова- ния
RasDialDlg, вам не нужно задавать этот флаг,
ГЛАВА 16 Клиент службы RAS 505Ш bwndParent — не используется и должен быть равен
NULLШ reserved — не используется и должен иметь значение 0
Ш reservedl — зарезервирован для будущего использования в Windows 2000
и должен иметь значение 0
• RasEapInfo — в Windows 2000 позволяет указать информацию протоко- ла Extensible Authentication Protocol (EAP)
В
RasDial параметр
ipszPhonebook идентифицирует путь к файлу телефон- ного справочника в Windows 2000 и NT В Windows 95, 98 и СЕ этот пара- метр должен иметь значение
NULL, так как телефонный справочник хранит- ся в системном реестре
Телефонный справочник (phonebook) — это сово- купность свойств набора номера RAS, определяющих способ установки RAS- соединения
RasDial использует достаточно много свойств набора номера
Подробней мы поговорим об этом позже
Указатель
ipRasDialParams структуры
RASDIALPARAMS определяет парамет- ры набора номера и аутентификации пользователя, которые использует функция
RasDial для установления удаленного соединения
typedef struct .RASDIALPARAMS { >иDWORD dwSize, SP- <•TCHAR szEntryName[RAS_MaxEntryName + 1], уTCHAR szPhoneNumber[RAS_MaxPhoneNumber + 1], .,TCHAR szCallbackNumber[RAS_MaxCallbackNumber + 1];TCHAR szUserName[UNLEN + 1],TCHAR szPassword[PWLEN + 1],TCHAR szDomain[DNLEN + 1] ;#if (WINVER >= 0x401)DWORD dwSubEntry,DWORD dwCallbackld;#endif> RASDIALPARAMS,RASDIALPARAMS имеет следующие поля
•
dwSize — размер структуры RASDIALPARAMS в байтах Это позволяет RAS
определять версию
WINVER, с которой вы работаете
Ш szEntryName — строка, позволяющая идентифицировать запись в теле- фонном справочнике (содержится в файле телефонного справочника,
указанном в параметре
IpszPhonebook функции
RasDial) Как мы уже го- ворили, записи в телефонном справочнике дают возможность точно на- страивать такие свойства RAS-соединения, как выбор модема или кадри- рующего протокола Однако указывать запись телефонного справочни- ка для использования
RasDial не обязательно Если это поле — пустая строка («»),
RasDial выберет первый доступный модем, установленный в системе, и с помощью следующего параметра —
szPhoneNumber, устано- вит соединение
• szPboneNumber — телефонный номер, который переопределяет номер из записи телефонного справочника, указанной в поле
szEntryName. 5 0 6 ЧАСТЬ III Служба удаленного доступа (RAS)
Я szCallbackNumbei— телефонный номер, по которому RAS-сервер может установить с клиентом обратную связь. В этом случае сервер разорвет первоначальное соединение и сам установит связь с клиентом по ука- занному номеру. Это удобное свойство позволяет серверу узнать, что за пользователь к нему подсоединяется.
Ш szUserName — идентифицирует имя пользователя, используемое для его аутентификации на сервере.
И
szPassword — идентифицирует пароль, используемый для аутентифика- ции пользователя на сервере.
II
szDomain — идентифицирует домен Windows 2000 или Windows NT, на котором размещена учетная запись пользователя.
•
dwSubEntry — дополнительно позволяет указывать первоначальную под- запись телефонного справочника для подключения к многоканальному соединению RAS (будут рассмотрены далее).
Ш dwCallbackld — позволяет передавать определенное приложением зна- чение в функцию обратного вызова
RasDialFunc2 (которая тоже будет описана позже). Если вы не используете эту функцию обратного вызова,
то данное поле не применяется.
Следующие параметры —
dwNotifierType и
IpvNotifier, определяют режим работы
RasDial (синхронно или асинхронно она вызывается). Последний параметр —
iphRasConn, указывает на описатель RAS-соединения типа
HRAS-CONN. Перед вызовом
RasDial нужно присвоить этому параметру значение
NULL. Если
RasDial выполняется успешно, то возвращается ссылка на описа- тель RAS-соединения.
Теперь рассмотрим, как вызывается
RasDial. Как уже упоминалось, у
Ras-Dial два. режима работы: синхронный и асинхронный. В синхронном режи- ме
RasDial блокируется, пока не будет завершена или отклонена установка соединения. В асинхронном режиме
RasDial завершает установку соедине- ния сразу, позволяя приложению выполнять в это время другие действия.
MlСинхронный режим |Если параметр
IpvNotifier функции
RasDial равен
NULL, RasDial будет работать синхронно, а параметр
dwNotifierType игнорируется. Это наиболее простой способ работы с
RasDial, однако в этом
случае вы не сможете отслеживать соединение, как в асинхронном режиме. Листинг 16-1 показывает, как выз- вать
RasDial в синхронном режиме. Заметьте, что этот код не задает телефон- ный справочник или запись справочника — он лишь демонстрирует, как сформировать RAS-соединение.
Листинг 16-1. Синхронный вызов RasDialRASDIALPARAMS RasDialParams;
IUHRASCONN hRasConn;
DWORD Ret; ff
II Всегда задавайте
размер структуры RASDIALPARAMS