1 Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР) Кафедра автоматизированных систем управления (АСУ) А.Я. Суханов Сети ЭВМ и телекоммуникации. Учебное методическое пособие по лабораторным занятиям, самостоятельной и индивидуальной работе студентов направления 230100 Информатика и вычислительная техника 2012 2 Суханов А.Я. Сети ЭВМ и телекоммуникации: Учебное методическое пособие по лабораторным занятиям, самостоятельной и индивидуальной работе студентов – 65 с. Учебное методическое пособие содержит программу и задания для лабораторных занятий, а так же все необходимые формы документов для выполнения лабораторных заданий. Суханов А.Я., 2012 3 Содержание ВВЕДЕНИЕ ...................................................................................................................................................................... 4 1. ЦЕЛИ И ЗАДАЧИ ДИСЦИПЛИНЫ, ЕЕ МЕСТО В УЧЕБНОМ ПРОЦЕССЕ ............................................... 5 1.2. ЗАДАЧИ ИЗУЧЕНИЯ СЕТЕЙ И ТЕЛЕКОММУНИКАЦИЙ. .............................................................................................. 5 1.3. ПЕРЕЧЕНЬ ДИСЦИПЛИН, УСВОЕНИЕ КОТОРЫХ СТУДЕНТАМИ НЕОБХОДИМО ДЛЯ ИЗУЧЕНИЯ БАЗ ДАННЫХ И ЭКСПЕРТНЫХ СИСТЕМ. ................................................................................................................................................... 5 2. СОДЕРЖАНИЕ КУРСА ............................................................................................................................................ 5 2.1 ЛЕКЦИИ (54 ЧАСА) ................................................................................................................................................... 5 2.2 ТЕМЫ ДЛЯ САМОСТОЯТЕЛЬНОГО ИЗУЧЕНИЯ. ОТЧЕТ В ВИДЕ РЕФЕРАТОВ И ДОКЛАДОВ. .......................................... 7 2.3 ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ ............................................................................................................................... 8 2.3.1 Экзаменационные билеты ............................................................................................................................. 9 3. ЛАБОРАТОРНЫЕ РАБОТЫ .................................................................................................................................. 12 3.1 РАБОТА С WINSOCKET ............................................................................................................................................ 12 3.1.1 Определения .................................................................................................................................................. 12 3.1.2 Создание сервера .......................................................................................................................................... 12 3.1.3 Создание клиента......................................................................................................................................... 15 3.2 ЛАБОРАТОРНАЯ РАБОТА №1 РАБОТА С СОКЕТАМИ БЕРКЛИ.................................................................................... 16 Протокол передачи времени Time ........................................................................................................................ 17 Протокол Finger .................................................................................................................................................... 18 Задание на лабораторную работу: ..................................................................................................................... 19 3.3 ЛАБОРАТОРНАЯ РАБОТА №2 ПРОТОКОЛЫ SMTP И POP3 ...................................................................................... 19 3.4 ЛАБОРАТОРНАЯ РАБОТА №3 МОДЕЛИРОВАНИЕ ПРОТОКОЛОВ КАНАЛЬНОГО УРОВНЯ ........................................... 24 3.5 ЛАБОРАТОРНАЯ РАБОТА №4 БРАУЗЕР И FTP-КЛИЕНТ............................................................................................. 29 3.6 ЛАБОРАТОРНАЯ РАБОТА №5. HTML, JAVASCRIPT ТЕХНОЛОГИЯ PHP .................................................................... 30 HTML и Javascript.................................................................................................................................................. 30 Технология PHP ..................................................................................................................................................... 34 3.7 ЛАБОРАТОРНАЯ РАБОТА № 6. ТЕХНОЛОГИЯ XML ................................................................................................. 36 3.8 ЛАБОРАТОРНАЯ РАБОТА №7 МАРШРУТИЗАЦИЯ В ВС ........................................................................................... 40 3.9 ЛАБОРАТОРНАЯ РАБОТА №8 КЭШИРУЮЩИЙ HTTP ПРОКСИ-СЕРВЕР И SOCKS5 ПРОКСИ-СЕРВЕР ....................... 46 3.10 ЛАБОРАТОРНАЯ РАБОТА №9 РАСПРЕДЕЛЕННЫЙ UDP СЕРВЕР/ UDP КЛИЕНТ ....................................................... 58 3.11 ЛАБОРАТОРНАЯ РАБОТА 10. ПЕРЕХВАТ СЕТЕВЫХ ПАКЕТОВ ................................................................................. 60 3.12 ЛАБОРАТОРНАЯ РАБОТА 11. SASL АУТОИНТЕФИКАЦИЯ ...................................................................................... 64 ЛИТЕРАТУРА ................................................................................................................................................................ 65 4 Введение Методическое пособие предназначено для студентов направления 230100 очной формы обучения и содержит рабочую программу дисциплины «Сети и телекоммуникации», руководство для выполнения лабораторных работ, задания для контрольной работы по вариантам, экзаменационные вопросы по дисциплине. Выполнение заданий поможет лучше усвоить теоретический материал и получить практические навыки при работе с базами данных и экспертными системами. Лабораторные работы по дисциплине «Сети ЭВМ и телекоммуникации» у студентов направления бакалавриата 230100 «Информатики и вычислительная техника» проводятся в пятом семестре четырехлетнего учебного цикла. Учитывая специфику направления, основной акцент сделан на программном обеспечении для сетей ЭВМ. Базовой, но не единственной, технологией программирования на сетевом и транспортном уровне эталонной модели взаимодействия открытых систем (ISO/OSI) являются сокеты (socket) Беркли. Сокеты Беркли в настоящее время реализованы в виде прикладного интерфейса (API) практически во всех современных операционных системах. В связи с широким распространением сетей ЭВМ и телекоммуникаций на сегодняшний день знание этой технологии является необходимым для специалиста в области программного обеспечения. Мировые тенденции развития сетевых технологий указывают на то, что технология программирования сокетов эволюционирует, становится протоколо- и платформонезависимой и имеет широкие перспективы в будущем. В тоже время программирование сокетов является достаточно низкоуровневой технологией, сосредотачивающей внимание на транспортировке данных безотносительно их пользовательской семантики. Для реализации законченных пользовательских приложений требуется применение более эффективных высокоуровневых технологий передачи гипертекста, бинарных данных (HTTP, FTP), и организации логики клиент-серверного взаимодействия (веб-технологии). Также мощной тенденцией развития программного обеспечения вообще и сетевого в частности является создание технологий программирования максимально независимых от программного и аппаратного окружения. Ярчайшим примером здесь является технология Java корпорации Sun Microsystems (США) и свободно распространяемая среда разработки Eclipse, продвигаемая одноименным сетевым сообществом (community). Студент должен обладать некоторым набором знаний и навыков для выполнения данного лабораторного практикума. Так, для работы с сокетами в ОС MS Windows и Unixподобных системах, требуется знание языка программирования C, а также основ работы в соответствующих ОС. Язык программирования Java является развитием ЯП C++, и для освоения Java необходимо владеть методами объектно-ориентированного проектирования и программирования. Теоретические знания о построении сетей ЭВМ приобретаются в ходе лекционных занятий и при изучении основной и дополнительной литературы. Программное обеспечение, а также справочная информация, используемые в данном практикуме, являются свободно распространяемыми и доступны для загрузки из сети Интернет. Для экономии времени всё обеспечение загружено, упорядочено в структуру и размещено на локальных и публичных сетевых ресурсах. Одним из таких ресурсов является веб-узел афедры АСУ ТУСУР http: //www.asu.tusur.ru (раздел методического обеспечения. Можно указать то место, где установлена IDE Eclipse. 5 1. ЦЕЛИ И ЗАДАЧИ ДИСЦИПЛИНЫ, ЕЕ МЕСТО В УЧЕБНОМ ПРОЦЕССЕ 1.1. Цели преподавания дисциплины Целью дисциплины является обучение студентов основам построения и функционирования вычислительных сетей (ВС) и телекоммуникационных систем (ТКС). На материале этой дисциплины базируются практически все дисциплины связанные с применением технологий вычислительных сетей. 1.2. Задачи изучения сетей и телекоммуникаций. Основной задачей изучения дисциплины является приобретение студентами прочных знаний и практических навыков в области, определяемой основной целью курса. В результате изучения дисциплины студенты должны усвоить следующие понятия и определения: классификация информационно-вычислительных сетей, способы коммутации, взаимодействие программного и аппаратного обеспечения сетей, протоколы и интерфейсы, эталонная модель взаимосвязи открытых систем, аналоговые и цифровые каналы передачи данных, модемы, базовые технологии локальных сетей, глобальные сети, технологии современных телекоммуникаций. В части организации программного обеспечения сетей изучаются способы адресации в протоколах TCP/IP, алгоритмы маршрутизации, протоколы файлового обмена, электронной почты, дистанционного управления, Web-технологии, способы организации распределенных вычислений, основные возможности сетевых операционных систем. Рассматриваются как низкоуровневые (сокеты) так и высокоуровневые программные технологии (технология Java, .Net) для работы в вычислительных сетях. 1.3. Перечень дисциплин, усвоение которых студентами необходимо для изучения баз данных и экспертных систем. Дисциплина «Сети и телекоммуникации» относится к профессиональному циклу базовой (обязательной) части дисциплин. Изучение данной дисциплины необходимо для учебно-исследовательской работы и при изучении GRID-технологий. Для изучения данной дисциплины необходимо изучение таких дисциплин на младших курсах таких как: «Математика», «Физика», «Информатика», «Программирование», «Дискретная математика», «ЭВМ и периферийные устройства», «Объектно-ориентированное программирование», «Структуры и алгоритмы обработки данных», «Основы разработки программного обеспечения». 2. Содержание курса Наименование разделов Введение Содержание разделов Трудоемкость (час.) 2.1 Лекции (54 часа) Предмет и содержание курса. Вычислительные машины, сети 2 и системы телекоммуникаций - важный фактор научнотехнического прогресса и прогресса цивилизации. Различие 6 Основы передачи данных Принципы построения сетей ЭВМ Прикладной уровень модели ВОС. Транспортный, сеансовый уровни и уровень представления Сетевой уровень модели ВОС Канальный уровень модели ВОС Физический уровень модели ВОС Базовые технологии сетей. Современные телекоммуникационн ые системы Стеки сетевых протоколов Программное понятий вычислительная машина и вычислительная сеть. История и современные тенденции развития вычислительных сетей. Задачи, решаемые современными вычислительными сетями: файловый сервис, сервис печати, сервис сообщений, сервис приложений, сервис баз данных. Понятие среды передачи данных. Характеристики сред. Шкала электромагнитных колебаний. Стандарты сред передачи данных. Понятие полосы пропускания. Количество информации и энтропия, единицы измерения. Законы Найквиста, Шеннона, Котельникова. Аналоговая и цифровая формы представления информационного сигнала. Способы модуляции. Информационная и техническая скорость передачи. Алгоритмы кодирования и сжатия информации. Классификация сетей. Многоуровневый подход к организации сетей. Протоколы и интерфейсы. Стандарты и источники стандартов ВС. Открытые системы. Модель взаимодействия открытых систем (ВОС). Понятие стека протоколов. Взаимодействие различных уровней стека. Сервисы прикладного уровня. Оповещение о сервисах. Использование сервисов. Разрешение имен. Адресация транспортного соединения. Сегментация, блокирование, сцепление данных. Алгоритм медленного пуска. Сервис транспортного соединения. Задачи уровня представления. Шифрование. Задачи сетевого уровня. Сервис шлюзов. Адресация в сетях. Задача маршрутизации. Методы маршрутизации. Коммутация. Виртуальные каналы. Протоколы и алгоритмы групповой маршрутизации. Задачи канального уровня. Логическая топология. Методы доступа к среде передачи данных. Адресация канального уровня. Синхронизация передачи. Сервис соединения канального уровня. Задачи физического уровня. Типы соединения. Физическая топология. Аналоговое и цифровое представление сигнала. Синхронизация бит. Использование полосы пропускания. Мультиплексирование (TDMA, FDMA, CDMA, OFDMA). Ethernet, TokenRing, Frame Relay, ATM, FDDI, 100VG ANYLAN, Wifi, WiMax. Территориальные сети. Аппаратное обеспечение сетей: сетевые интерфейсные карты, концентраторы, коммутаторы, мосты, маршрутизаторы. Коммутируемые телефонные сети. Интегральные сети цифрового обслуживания. Сотовая телефония. Спутниковые системы связи и навигации. Низкоорбитальные и высокоорбитальные системы. Системы глобального позиционирования и синхронизации. Спутниковый Интернет. Система Iridium, GlobalStar, GPS, VSAT. Технологии сотовой связи. UMTS, GSM. TCP/IP (IPv4, IPv6, ICMP, DHCP, DNS, ARP, RARP, SCTP, UDP), IPX/SPX, SMB/NetBIOS, DNA, SNA, AppleTalk, DecNet, стек OSI. Определение сетевой ОС. Одноранговые сети и сети 4 4 2 4 4 2 4 8 4 4 4 7 обеспечение сетей. Сетевые операционные системы Глобальные сети. Языки и средства создания Webприложений. Безопасность в вычислительных сетях. «клиент\сервер». Обзор сетевых ОС (Unix, Win32, Novell Netware). Служба сетевых каталогов как средство интеграции сетевых продуктов. Драйверы сетевых устройств. Сокеты Беркли. Программирование на уровне сокетов. История возникновения и развития глобальных сетей (AOL, 4 Compuserv, Internet). Служба WWW. Язык гипертекстовой разметки HTML – основные возможности. Способы организации динамической обработки информации в WWW: на стороне сервера, на стороне клиента. Организация распределенных вычислений. Технологии SONET/SDH, 10\40\100\ Gigabit Ethernet. Общие правила безопасности. Классы безопасности. 4 Безопасность в ВС по ГОСТ. Понятие Firewall. Аутентификация. Безопасность беспроводных сетей, WEP, атаки на WEP, WPA, WPA2. Квантовые алгоритмы шифрования. DoS, DDoS атака, спуфинг, атака не переполнение буфера. 2.2 Темы для самостоятельного изучения. Отчет в виде рефератов и докладов. Темы рефератов 1. Протокол шифрования WEP. Взлом WEP. FMS Атака. 2. Протокол IPSec. 3. Протокол сетевого уровня IPv6. 4. Протокол SSL/TLS. 5. Технологии глобальных сетей. 6. Сотовая связь. Основные технологии. 7. Современные технологии локальных сетей. 8. Спутниковая связь, спутниковый Интернет. 9. Методы мультиплексирования применяемые в сотовой связи. 10. Телекоммуникационные технологии будущего. 11. Квантовые криптографические алгоритмы и протоколы для передачи данных. 12. Квантовая телепортация. 13. Безопасность в Wi - Fi сетях. 14. Стек протоколов OSI. 15. Сети ЭВМ будущего. 16. Протоколы групповой маршрутизации. 17. Защищенные каналы в сети Интернет. 18. Безопасность в сети Интернет. Основные угрозы. 19. DDoS атака. DoS атака. 20. Облачные сервисы. 21. Сети WiMAX. 8 2.3 Экзаменационные вопросы 1. Виды сервисов, предоставляемых современными сетями. Привести примеры существующих технологий. 2. Глобальные и локальные сети. Современные тенденции развития. 3. Необходимость стандартизации сетей ЭВМ. Источники официальных стандартов и рекомендаций. Источники стандартов Интернет. 4. Модель взаимодействия открытых систем. Принцип построения. Понятия: протокол, интерфейс. 5. Понятие среды передачи данных. Шкала электромагнитного спектра. Достоинства и недостатки каждого из диапазонов. 6. Проводные технологии передачи данных. Основные характеристики. 7. Беспроводные технологии передачи данных. Основные характеристики. 8. Спутниковые системы передачи данных. Низко- и высокоорбитальные системы. VSAT. Iridium. GlobalStar. Глонасс. GPS. 9. Телефония и магистральные каналы связи. Технологии T1, E1, T3, X.25, Frame Relay, ISDN, ATM. 10. Аппаратное обеспечение сетей ЭВМ (сетевые карты, мосты, коммутаторы, маршрутизаторы, модемы, мультиплексоры). Разделение устройств по уровням OSI. 11. Понятие стека протоколов. Существующие стеки протоколов (назвать не менее 4-5 стеков). Стеки TCP/IP и IPX/SPX. Принципиальное отличие этих стеков. 12. Пример взаимодействие двух компьютеров в сети. Клиент и сервер. Задачи решаемые, сетевыми операционными системами. Обзор сетевых операционных систем. Основные критерии оценки. 13. Коммутация пакетов и коммутация каналов. Сравнительная характеристика, области и технологии применения. 14. Аналоговое и цифровое кодирование. Связь частоты, методов кодирования и информационной скорости передачи сигнала, энтропия: формула Шеннона. 15. Физический уровень модели OSI. Единицы данных физического уровня. Методы синхронизации бит. Физическая топология. Достоинства и недостатки различных топологий. Мультиплексирование физического уровня: методы мультиплексирования, области применения. Методы помехоустойчивого кодирования. 16. Канальный уровень модели OSI. Логическая топология сетей. Единицы данных канального уровня. Методы доступа к среде передачи данных. Синхронизация байт. Сервис соединений. 17. Технологии канального уровня: Ethernet, Token Ring. 18. Технология 100 VG-AnyLAN, FDDI. 19. Сетевой уровень модели OSI. Единицы данных, адресация сетевого уровня. Сервис шлюзов. Маршрутизация. Коммутация. 20. Транспортный уровень модели OSI. Сервис транспортного уровня. Сегменты. 21. Сеансовый, уровень представления и прикладной уровни. 22. Адресация в сетях. Адресация в сетях TCP/IP. Протоколы ARP, DHCP. 23. Алгоритм Дейкстры нахождения кратчайшего пути. Метод заливки. 24. Маршрутизация по вектору расстояний. Достоинства и недостатки методов. 25. Маршрутизация с учетом состояния линий. 26. Протокол IP. Назначение. Принцип действия. Формат заголовка. 27. Протоколы: UDP, ICMP, TCP, ICMP v6. 28. Протокол SOCKS5. Цепочки прокси. 29. Система DNS. Записи ресурсов в DNS. Серверы имен. Зоны DNS. 30. Электронная почта. К какому виду сетевого сервиса она относится? Стандарты email. Почему неудобно использовать IP адреса в качестве адресов электронной почты? 31. Архитектура и службы электронной почты. Пользовательский агент и агент передачи сообщения. Перечислите протоколы электронной почты Internet. 9 32. Форматы сообщений. RFC822. MIME. Правила кодировки base64, quoted-printable. 33. Протоколы SMTP, POP3, IMAP4. Назначение. Основные отличия. Веб-почта. 34. Всемирная паутина WWW. История развития. Архитектура и принцип действия. Вопросы, рассматриваемые W3C. 35. Клиентское ПО в WWW. Действия выполняемые браузером. Способы расширения возможностей браузеров. 36. ПО веб-сервера. Действия сервера. Способы увеличения производительности серверов. Популярное ПО для веб-серверов (Apache и т.д.) 37. Протокол HTTP. 38. URL. URN. Технология cookie. Достоинства и недостатки. 39. Статические веб-документы. HTML – основные свойства. Сравнение возможностей различных версий HTML. Формы в HTML. 40. XML, XSL. XHTML. 41. Динамические веб-документы на стороне сервера. Назначение. Примеры реализации. Технологии CGI, ISAPI, PHP, ASP, JSP. Примеры кода. Достоинства и недостатки. 42. Динамические веб-документы на стороне клиента. JavaScript, Java, ActiveX, SWF. Примеры реализации. Достоинства и недостатки. 43. Описание сервиса в модели OSI. Функции уровней. 44. Представление сервиса в модели OSI. Правила описания сервиса. Взаимосвязь в режиме без соединения. Описание сервисов физического и канального уровней. Граф последовательности канальных сервисных примитивов. 45. Описание сервисов сетевого и транспортного уровней. 46. Описание сервисов сеансового уровня. 47. Описание сервисов уровней представления и прикладного уровня. Синтаксис ASN.1 48. Сети Gigabit, 10,40, 100 Gigabit Ethernet. 49. Сети SONET/SDH. 50. Протокол маршрутизации OSPF. 51. Протокол маршрутизации NLSP. 52. Протокол маршрутизации RIP. 53. Протокол IP версии 6. Отличия от версии 4. IP адреса v6. 54. Способы расширения адресного пространства IP v4. Устройства NAT. 55. Протоколы групповой маршрутизации. 56. Протокол групповой маршрутизации MOSPF. 57. Протокол IGMP. 58. Беспроводные сети. Wi-Fi, WiMax, Bluetooth. 59. Протоколы беспроводных сетей. WEP. 60. Протоколы беспроводных сетей. WPA. 61. Безопасность в беспроводных сетях. 62. Сотовая связь. CDMA, TDMA, FDMA. 63. Сотовая связь. UMTS, GSM. 64. Безопасность беспроводных сетей. Атаки на WEP. 65. Квантовые криптографические алгоритмы и протоколы. 66. Безопасность в сети. SSL 2.0. TLS (SSL 3.0). 67. Безопасность в сети. IPSec. 68. Безопасность в сети. SASL. 2.3.1 Экзаменационные билеты 1. Виды сервисов, предоставляемых современными сетями. Привести примеры существующих технологий. 10 2. Пример взаимодействие двух компьютеров в сети. Клиент и сервер. Задачи решаемые, сетевыми операционными системами. Обзор сетевых операционных систем. Основные критерии оценки. 3. Протоколы SMTP, POP3, IMAP4. Назначение. Основные отличия. Веб-почта. –-------------------------------------------4. Электронная почта. К какому виду сетевого сервиса она относится? Стандарты e-mail. Почему неудобно использовать IP адреса в качестве адресов электронной почты? 5. Протоколы беспроводных сетей. WEP. 6. Динамические веб-документы на стороне сервера. Назначение. Примеры реализации. Технологии CGI, ISAPI, PHP, ASP, JSP. Примеры кода. Достоинства и недостатки. –--------------------------------------------7. Технологии канального уровня: Ethernet, Token Ring. 8. Маршрутизация с учетом состояния линий. 9. Архитектура и службы электронной почты. Пользовательский агент и агент передачи сообщения. Перечислите протоколы электронной почты Internet. –------------------------------------------------10. Транспортный уровень модели OSI. Сервис транспортного уровня. Сегменты. 11. Сетевой уровень модели OSI. Единицы данных, адресация сетевого уровня. Сервис шлюзов. Маршрутизация. Коммутация. 12. Протокол маршрутизации OSPF. –---------------------------------------------------13. Протокол маршрутизации NLSP. 14. Беспроводные сети. Wi-Fi, WiMax, Bluetooth. 15. Канальный уровень модели OSI. Логическая топология сетей. Единицы данных канального уровня. Методы доступа к среде передачи данных. Синхронизация байт. Сервис соединений. –----------------------------------------------------16. Беспроводные технологии передачи данных. Основные характеристики. 17. Физический уровень модели OSI. Единицы данных физического уровня. Методы синхронизации бит. Физическая топология. Достоинства и недостатки различных топологий. Мультиплексирование физического уровня: методы мультиплексирования, области применения. Методы помехоустойчивого кодирования. 18. Технология 100 VG-AnyLAN, FDDI. –----------------------------------------------------------------19. Описание сервиса в модели OSI. Функции уровней. 20. Представление сервиса в модели OSI. Правила описания сервиса. Взаимосвязь в режиме без соединения. Описание сервисов физического и канального уровней. Граф последовательности канальных сервисных примитивов. 21. Безопасность в сети. SSL 2.0. TLS (SSL 3.0). –-------------------------------------------------------------------22. Аппаратное обеспечение сетей ЭВМ (сетевые карты, мосты, коммутаторы, маршрутизаторы, модемы, мультиплексоры). Разделение устройств по уровням OSI. 23. Аналоговое и цифровое кодирование. Связь частоты, методов кодирования и информационной скорости передачи сигнала, энтропия: формула Шеннона. 24. Система DNS. Записи ресурсов в DNS. Серверы имен. Зоны DNS. ---------------------------------------------------------------------25. Протокол SOCKS5. Цепочки прокси. 26. ПО веб-сервера. Действия сервера. Способы увеличения производительности серверов. Популярное ПО для веб-серверов (Apache и т.д.) 27. Описание сервисов сеансового уровня. –------------------------------------------------------------ 11 28. Сеансовый, уровень представления и прикладной уровни. 29. Понятие среды передачи данных. Шкала электромагнитного спектра. Достоинства и недостатки каждого из диапазонов. 30. Спутниковые системы передачи данных. Низко- и высокоорбитальные системы. VSAT. Iridium. GlobalStar. Глонасс. GPS. –---------------------------------------------------------------------31. URL. URN. Технология cookie. Достоинства и недостатки. 32. Динамические веб-документы на стороне клиента. JavaScript, Java, ActiveX, SWF. Примеры реализации. Достоинства и недостатки. 33. Описание сервисов сетевого и транспортного уровней. –-----------------------------------------------------------------------34. Безопасность в сети. SASL. 35. Протоколы беспроводных сетей. WPA. 36. Форматы сообщений. RFC822. MIME. Правила кодировки base64, quoted-printable. –------------------------------------------------------------------37. Протокол IP. Назначение. Принцип действия. Формат заголовка. 38. Адресация в сетях. Адресация в сетях TCP/IP. Протоколы ARP, DHCP. 39. Понятие стека протоколов. Существующие стеки протоколов (назвать не менее 4-5 стеков). Стеки TCP/IP и IPX/SPX. Принципиальное отличие этих стеков. –-----------------------------------------------------------------------40. Глобальные и локальные сети. Современные тенденции развития. 41. Алгоритм Дейкстры нахождения кратчайшего пути. Метод заливки. 42. Клиентское ПО в WWW. Действия выполняемые браузером. Способы расширения возможностей браузеров. –-------------------------------------------------------------------------------43. Статические веб-документы. HTML – основные свойства. Сравнение возможностей различных версий HTML. Формы в HTML. 44. Сети Gigabit, 10,40, 100 Gigabit Ethernet. 45. Протокол IP версии 6. Отличия от версии 4. IP адреса v6. –----------------------------------------------------------------------------46. Протокол групповой маршрутизации MOSPF. 47. Безопасность беспроводных сетей. Атаки на WEP. 48. Протоколы: UDP, ICMP, TCP, ICMP v6. -----------------------------------------------------------------------------49. Всемирная паутина WWW. История развития. Архитектура и принцип действия. Вопросы, рассматриваемые W3C. 50. Необходимость стандартизации сетей ЭВМ. Источники официальных стандартов и рекомендаций. Источники стандартов Интернет. 51. Модель взаимодействия открытых систем. Принцип построения. Понятия: протокол, интерфейс. –-----------------------------------------------------------------------------52. Коммутация пакетов и коммутация каналов. Сравнительная характеристика, области и технологии применения. 53. Маршрутизация по вектору расстояний. Достоинства и недостатки методов. 54. Протокол HTTP. –-----------------------------------------------------------------------------------55. Протокол IGMP. 56. Квантовые криптографические алгоритмы и протоколы. 57. XML, XSL. XHTML. –-----------------------------------------------------------------------------------58. Описание сервисов уровней представления и прикладного уровня. Синтаксис ASN.1 59. Способы расширения адресного пространства IP v4. Устройства NAT. 12 60. Телефония и магистральные каналы связи. Технологии T1, E1, T3, X.25, Frame Relay, ISDN, ATM. –--------------------------------------------------------------------------------61. Проводные технологии передачи данных. Основные характеристики. 62. Сети SONET/SDH. 63. Сотовая связь. CDMA, TDMA, FDMA. –---------------------------------------------------------------------------------64. Сотовая связь. UMTS, GSM. 65. Безопасность в сети. IPSec. 66. Протоколы групповой маршрутизации. –-------------------------------------------------------------------------------------67. Протокол маршрутизации RIP. 68. Безопасность в беспроводных сетях. 69. Коммутация пакетов и коммутация каналов. Сравнительная характеристика, области и технологии применения. 3. Лабораторные работы 3.1 Работа с WinSocket 3.1.1 Определения Socket (гнездо, разъем) - абстрактное программное понятие, используемое для обозначения в прикладной программе конечной точки канала связи с коммуникационной средой, образованной вычислительной сетью. При использовании протоколов TCP/IP можно говорить, что socket является средством подключения прикладной программы к порту локального узла сети. 3.1.2 Создание сервера Для создания сокета в операционной системе служит системный вызов socket(). Для транспортных протоколов семейства TCP/IP существует два вида сокетов: UDP-сокет – сокет для работы с датаграммами, и TCP сокет – для работы с каналами. При создании сокета необходимо точно специфицировать его тип. Эта спецификация производится с помощью трех параметров вызова socket(). Первый параметр указывает, к какому семейству протоколов относится создаваемый сокет, а второй и третий параметры определяют конкретный протокол внутри данного семейства. Создание сокета осуществляется следующим системным вызовом: #include <sys/types.h> #include <sys/socket.h> int socket (int domain, int type, int protocol) Аргумент domain задает используемый для взаимодействия набор протоколов (вид коммуникационной области), для стека протоколов TCP/IP он должен иметь символьное значение AF_INET или PF_INET. Аргумент type задает режим взаимодействия: SOCK_STREAM - с установлением соединения; SOCK_DGRAM - без установления соединения. Аргумент protocol задает конкретный протокол транспортного уровня (из нескольких возможных в стеке протоколов). Если этот аргумент задан равным 0, то будет использован протокол "по умолчанию" (TCP для SOCK_STREAM и UDP для SOCK_DGRAM при использовании комплекта протоколов TCP/IP). При удачном завершении своей работы данная функция возвращает дескриптор сокета - целое неотрицательное число, однозначно его идентифицирующее. При обнаружении ошибки в ходе своей работы функция возвращает число "-1". Прежде чем воспользоваться функцией socket необходимо проинициализировать 13 процесс библиотеки wsock32.dll вызвав функцию WSAStartup например: WSADATA WsaData; int err = WSAStartup (0x0101, &WsaData); if (err == SOCKET_ERROR) { printf ("WSAStartup() failed: %ld\n", GetLastError ()); return 1; } Здесь 0х0101 версия библиотеки которую следует использовать. Кроме того, не забудьте подключить к проекту библиотеку ws2_32.lib. Теперь объявить переменную типа SOCKET можно следующим образом: s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); Далее следует задать параметры для сокета (сервера) для этого нам необходимо объявить структуру SOCKADDR_IN sin примерно следующим образом: SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(80); sin.sin_addr.s_addr = INADDR_ANY; Структура SOCKADDR_IN используется несколькими системными вызовами и функциями socket-интерфейса, ее определение в файле in.h выглядит следующим образом: struct SOCKADDR_IN { short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; Поле sin_family определяет используемый формат адреса (набор протоколов), в нашем случае (для TCP/IP) оно должно иметь значение AF_INET. Поле sin_addr содержит адрес (номер) узла сети. Поле sin_port содержит номер порта на узле сети. Поле sin_zero не используется. Определение структуры in_addr (из того же файла in.h) таково: struct in_addr { union { u_long S_addr; /* другие (не интересующие нас) члены объединения */ } S_un; #define s_addr S_un.S_addr }; Структура SOCKADDR_IN должна быть полностью заполнена перед выдачей системного вызова bind. При этом, если поле sin_addr.s_addr имеет значение INADDR_ANY, то системный вызов будет привязывать к сокету c номером (адресом) локального узла сети. Для подключения сокета к коммуникационной среде, образованной вычислительной сетью, необходимо выполнить системный вызов bind, определяющий в принятом для сети формате локальный адрес канала связи со средой. В сетях TCP/IP socket связывается с локальным портом. Системный вызов bind имеет следующий синтаксис: int bind (SOCKET s, SOCKADDR_IN *addr, int addrlen) Пример: err = bind( s, (LPSOCKADDR)&sin, sizeof(sin) ); Аргумент s задает дескриптор связываемого сокета. Аргумент addr в общем случае должен указывать на структуру данных, содержащую локальный адрес, приписываемый сокету. Для сетей TCP/IP такой структурой является SOCKADDR_IN. 14 Аргумент addrlen задает размер (в байтах) структуры данных, указываемой аргументом addr. В случае успеха bind возвращает 0, в противном случае - "-1". Для установления связи "клиент-сервер" используются системные вызовы listen и accept (на стороне сервера), а также connect (на стороне клиента). Для заполнения полей структуры sockaddr_in, используемой в вызове connect, обычно используется библиотечная функция gethostbyname, транслирующая символическое имя узла сети в его номер (адрес). Системный вызов listen выражает желание выдавшей его программы- сервера ожидать запросы к ней от программ-клиентов и имеет следующий вид: int listen (SOCKET s, int n); Пример: err = listen(s, SOMAXCONN); Аргумент s задает дескриптор сокета, через который программа будет ожидать запросы к ней от клиентов. Socket должен быть предварительно создан системным вызовом socket и обеспечен адресом с помощью системного вызова bind. Аргумент n определяет максимальную длину очереди входящих запросов на установление связи. Если какой-либо клиент выдаст запрос на установление связи при полной очереди, то этот запрос будет отвергнут. Признаком удачного завершения системного вызова listen служит нулевой код возврата. Перед тем как воспользоваться функцией accept, необходимо объявить ещё одну переменную типа SOCKET, например s1 . SOCKADDR_IN from; int fromlen=sizeof(from); s1 = accept(s,(struct sockaddr*)&from,&fromlen); Это сделано для того, что бы узнать IP адрес и порт удаленного компьютера. Для приема запросов от программ-клиентов на установление связи в программахсерверах используется системный вызов accept, имеющий следующий прототип: int accept (SOCKET s, sockaddr_in *addr, int *p_addrlen; Аргумент s задает дескриптор сокета, через который программа-сервер получила запрос на соединение (посредством системного запроса listen ). Аргумент addr должен указывать на область памяти, размер которой позволял бы разместить в ней структуру данных, содержащую адрес сокета программы-клиента, сделавшей запрос на соединение. Никакой инициализации этой области не требуется. Аргумент p_addrlen должен указывать на область памяти в виде целого числа, задающего размер (в байтах) области памяти, указываемой аргументом addr. Системный вызов accept извлекает из очереди, организованной системным вызовом listen, первый запрос на соединение и возвращает дескриптор нового (автоматически созданного) сокета с теми же свойствами, что и socket, задаваемый аргументом s. Этот новый дескриптор необходимо использовать во всех последующих операциях обмена данными. Если очередь запросов на момент выполнения accept пуста, то программа переходит в состояние ожидания поступления запросов от клиентов на неопределенное время (хотя такое поведение accept можно и изменить). Признаком неудачного завершения accept служит отрицательное возвращенное значение (дескриптор сокета отрицательным быть не может). После установления соединения с клиентом можно передавать и получать данные. Для этого в операционной системе Window используются системные вызовы recv для чтения и send для записи. Системные вызовы recv и send имеют следующие прототипы: int recv (SOCKET s, void *buf, size_t len, int flags); int send (SOCKET s, const void *buf, size_t len, int flags); Возвращаемое значение: 15 число принятых или переданных байтов в случае успеха или -1 в случае ошибки Аргумент s задает дескриптор сокета, через который принимаются данные. Аргумент buf для вызова recv указывает на область памяти, предназначенную для размещения принимаемых данных, а для вызова send - область памяти, содержащая передаваемые данные. Аргумент len задает размер (в байтах) области buf. Аргумент flags зависит от системы, но и UNIX, и Windows поддерживают следующие флаги: MSG_OOB – следует послать или принять срочные данные. MSG_PEEK – используется для просмотра поступивших данных без их удаления из приемного буфера. После возврата из системного вызова данные еще могут быть получены при последующем вызове recv. MSG_DONTROUTE – сообщает ядру, что не надо выполнять обычный алгоритм маршрутизации. Как правило, используется программами маршрутизации или для диагностических целей. При работе с протоколом TCP вам ничего больше не понадобиться. Но при работе с UDP нужны еще системные вызовы recvfrom и sendto. Они очень похожи на recv и send, но позволяют при отправке датаграммы задать адрес назначения, а при приеме – получить адрес источника. Системные вызовы recvfrom и sendto имеют следующие прототипы: int recvfrom (SOCKET s, void *buf, size_t len, int flags, struct socketaddt *from, int *fromlen); int sendto (SOCKET s, const void *buf, size_t len, int flags, const struct sockaddr *to, int tolen); Возвращаемое значение: число принятых или переданных байтов в случае успеха или -1 в случае ошибки Первые четыре аргумента – s, buf, len и flags – такие же, как и в вызовах recv и send. Аргумент from в вызове recvfrom указывает на структуру, в которую ядро помещает адрес источника пришедшей датаграммы. Длина этого адреса хранится в целом числе, на которое указывает аргумент fromlen. Обратите внимание, что fromlen – это указатель на целое. Аналогично аргумент to в вызове sendto указывает на адрес структуры, содержащей адреса назначения датаграммы, а аргумент tolen – длина этого адреса. Заметьте, что to - это целое, а не указатель. Для закрытия ранее созданного сокета в системе Windows используется системный вызов closesocket, а в UNIX – системный вызов close. Прототипы системных вызовов close и closesocket имеют следующий вид: int close(SOCKET s); int closesocket(SOCKET s); Аргумент s задает дескриптор ранее созданного сокета. 3.1.3 Создание клиента Программа клиента делается аналогично до момента создания сокетов. Cоздайте сокет так, как описано выше, но не пользуйтесь командой bind: SOCKADDR_IN anAddr; anAddr.sin_family = AF_INET; anAddr.sin_port = htons(80); anAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); Заполнение структуры производится почти также но во время инициализации переменной anAddr необходимо указать IP-адрес сервера ( пример 127.0.0.1 ) . Для обращения программы-клиента к серверу с запросом на установление логической соединения используется системный вызов connect, имеющий следующий прототип: int connect(SOCKET s, const struct sockaddr *peer, int peer_len)); 16 Аргумент s задает дескриптор сокета, через который программа обращается к серверу с запросом на соединение. Аргумент addr должен указывать на структуру данных, содержащую адрес, приписанный сокету программы-сервера, к которой делается запрос на соединение. Для сетей TCP/IP такой структурой является sockaddr_in. Для формирования значений полей структуры sockaddr_in удобно использовать функцию gethostbyname. Аргумент addrlen задает размер (в байтах) структуры данных, указываемой аргументом addr. Для того, чтобы запрос на соединение был успешным, необходимо, по крайней мере, чтобы программа-сервер выполнила к этому моменту системный вызов listen для сокета с указанным адресом. При успешном выполнении запроса системный вызов connect возвращает 0, в противном случае - "-1" (устанавливая код причины неуспеха в глобальной переменной errno). Примечание. В режиме взаимодействия без установления соединения необходимости в выполнении системного вызова connect нет. Однако, его выполнение в таком режиме не является ошибкой - просто меняется смысл выполняемых при этом действий: устанавливается адрес "по умолчанию" для всех последующих посылок дейтаграмм. 3.2 Лабораторная работа №1 Работа с сокетами Беркли Лабораторная работа №1 выполняется после изучения материала, посвященного описанию принципов работы с сокетами Беркли. Цель работы: написать консольные приложения на языке C/C++, реализующие работу протоколов Time, DayTime и Finger. Рекомендуемая литература: Глава 1 Работа с WinSocket данного пособия. Снайдер Й. Эффективное программирование TCP/IP. Библиотека программиста. – Спб: Питер, 2002. – 230 с.: ил. Электронный вариант лекций «Основы операционных систем. Практикум». Лекция 10 «Семейство протоколов TCP/IP. Сокеты (sockets) в UNIX и основы работы с ними». Лекции можно найти в архиве, в файле osintropractice.zip. Описание протокола Time в спецификации RFC-868 (Archive\Documents\ RFC\rfc868.txt) Описание протокола Finger в спецификации RFC-1288 (Archive\Documents\RFC\rfc1288.txt) Примитивы сокетов Беркли Сокет обычно трактуется как дескриптор файла и указывается в качестве параметра практически во всех примитивах. Примитивы сокетов для TCP SOCKET (гнездо) Дескриптор сокета, именование ресурса BIND (связать) Связывает ресурсы (сокет) с локальным адресом хоста LISTEN (ожидать) Возможность принять данные с указанием размера очереди ACCEPT (принять) Блокирует сервер до попытки соединения клиента CONNECT (соединить) Попытка установить соединения SEND (переслать) Посылает данные по соединению RECEIVE (получить) Получает данные у соединения CLOSE (закрыть) Разрывает соединение на стороне сервера и клиента примитивы используются в следующем порядке: Сторона сервера: 17 Вызовы примитивов осуществляются в следующем порядке: SOCKET - создает дескриптор (примерно так же как OPEN при открытии файла) и выделяет для него место в таблице транспортного объекта. При этом сообщается, какая служба необходима, канальная (TCP) или дейтаграммная (UDP). BIND – привязывает конкретный сетевой адрес к сокету, после чего становится возможной подключение клиентов. LISTEN – выделяет место для очереди входящих вызовов на случай одновременного обращения нескольких клиентов. ACCEPT – сервер переходит в режим ожидания (блокируется) до прихода блока с запросом соединения от клиента. При этом создается новый сокет, с теми же параметрами, что и оригинального сокета. Сервер может распараллелить процесс обработки нового сокета, что бы иметь возможность вернуться к ожиданию новых соединений. Сторона клиента: SOCKET - аналогично серверу. CONNECT – блокирует вызывающего до завершения процесса фазы установки соединения, т.е. до подтверждения сервера, что соединение установлено. Далее между сервером и клиентом идет обмен с использованием RECEIVE и SEND. Соединение разрывается, если обе стороны используют примитив CLOSE. Примечание. Для того чтобы выполнить преобразование символьного имени сервера или IP-адреса, в формат, используемый при работе с сетевыми функциями, следует использовать функции gethostbyname и inet_addr соответсвенно. Также, следует помнить, что аргументы и типы приведённых выше функций, могут различаться в разных ОС, поэтому, для получения более полной информации следует воспользоваться системой помощи в данной системе (команда man в UNIX или MSDN в Windows). При работе с сокетами в Windows, не забывайте подгрузить, а по окончании работы выгрузить библиотеку реализующую поддержку сокетов через функции WSAStartup/WSACleanup. Протокол передачи времени Time Данный протокол предназначен для передачи показаний времени по сети. В сети работают так называемые time-серверы, у которых можно запросить точное время. В ответ на запрос клиента, сервер возвращает время в секундах (32х битное двоичное число), прошедшее с 00:00:00 1 января 1900 года. Этот протокол может использовать в качестве транспортной службы как UDPпротокол, так и TCP-протокол. Стандартный порт протокола - 37. Если в качестве транспортной службы используется TCP, взаимодействие осуществляется так: SERVER: прослушивает 37 порт, ожидая соединений; CLIENT: запрашивает соединение с портом 37 сервера; SERVER: посылает время в виде двоичного 32х битного числа; CLIENT: получает время; SERVER: закрывает соединение; CLIENT: закрывает соединение; Если сервер по каким-либо причинам не может определить время на своей стороне, он отказывается от соединения, не посылая ничего. Если в качестве транспортной службы используется UDP, взаимодействие осуществляется так: SERVER: прослушивает 37 порт, ожидая соединений; CLIENT: посылает серверу пустой UDP-пакет, номер порта = 37; SERVER: получает пустой UDP-пакет; SERVER: посылает UDP-пакет, содержащий время в виде двоичного 32х битного 18 числа; CLIENT: получает UDP -пакет, содержащий время; Если сервер по каким-либо причинам не может определить время на своей стороне, он отбрасывает полученный пустой UDP-пакет и не посылает ничего в ответ. Протокол Finger Сетевой протокол Finger предназначен для предоставления информации о пользователях удалённого компьютера. Стандартный порт протокола - 79. Используя данный протокол, вы можете получить данные о списке пользователей, которые работают в данный момент на интересующей вас ЭВМ, о конкретном пользователе (дата последнего сеанса входа в систему и т.д.), о списке загруженных задач, о типах интерфейсов (например, терминалов). Протокол Finger обеспечивает интерфейс для удаленной информационной программы пользователя (RUIP - Remote User Information Program). Данный протокол базируется на TCP. Локальная ЭВМ осуществляет TCP-соединение с удаленным узлом через указанный порт. После этого становится доступной программа RUIP и пользователь может посылать ей свои запросы. Каждый запрос представляет собой строку текста. RUIP, получив запрос, анализирует его и присылает ответ, после чего соединение закрывается. Любые пересылаемые данные должны иметь формат ASCII, не иметь контроля по четности и каждая строка должна завершаться последовательностью CRLF (ASCII 13, за которым следует ASCII 10). Диалог двух машин через TCP выглядит следующим образом: SERVER: слушает порт 79; CLIENT: устанавливает соединение на 79 порт; CLIENT: посылает имя пользователя; SERVER: посылает информацию о запрашиваемом пользователе; CLIENT: принимает; SERVER: закрывает соединение; CLIENT: закрывает соединение; Пример реализации протокола Daytime В качестве примера, приводится текст программы, реализующей работу Daytime Protocol’а. #include <sys/types.h> #include <sys/socket.h> #include <sys/param.h> #include <sys/time.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <netdb.h> #include <memory.h> #include <unistd.h> #include <time.h> #define strHost "212.192.122.109" #define Port 13 int main(void) { int s, res; int nCharRecv; struct sockaddr_in clnt_sin; char timebuf[128]; if ((s=socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Cannot create socket!!!!\n"); 19 return -1; } memset ((char *)&clnt_sin, '\0', sizeof(clnt_sin)); clnt_sin.sin_family = AF_INET; clnt_sin.sin_addr.s_addr = inet_addr(strHost); clnt_sin.sin_port = htons(Port); res = connect (s, (struct sockaddr *)&clnt_sin, sizeof(clnt_sin)); if (res == -1) { perror("connect"); } else { printf("Connected\n"); } memset(timebuf, '\0', 128); nCharRecv = recv(s, &timebuf, sizeof(timebuf), 0); if (nCharRecv == -1) { printf("Cannot get info from server!!!!\n"); perror("Receive"); return -1; } close(s); printf("Time: %s\n", timebuf); return 0; } Задание на лабораторную работу: Ознакомившись с протоколом в RFC 868 написать программу, запрашивающую время с удаленного сервера через Time Protocol. Полученное от сервера 32 – битное число необходимо преобразовать в строку и вывести на экран. Написать программу, запрашивающую информацию о пользователе от удаленного сервера через протокол Finger, описанный в RFC 1288. Полученную информацию необходимо вывести на экран. Имя пользователя программа должна принимать из командной строки. Пользоваться готовыми классами, компонентами, библиотеками, реализующими работу с сетью, ЗАПРЕЩЕНО. Все программы должны использовать элементарные функции, работающими с сокетами Беркли. 3.3 Лабораторная работа №2 Протоколы SMTP и POP3 Лабораторная работа №2 выполняется после изучения материала, посвященного описанию принципов работы почтовых служб SMTP и POP3 [Компьютерные сети. 4-е издание / Э. Таненбаум]. Цель работы: написать GUI приложение для ОС Windows, реализующие работу протоколов SMTP или POP3. Рекомендуемая литература: Компьютерные сети. 4-е издание / Э. Таненбаум. – Спб.: Питер, 2003. – 992 с.:ил. Глава 7 («Прикладной уровень») раздел «Электронная почта». Описание протокола SMTP в спецификации RFC-788 (ARCHIVE\Documents\RFC\rfc788.txt). Описание протокола POP3 в спецификации RFC-1939 (ARCHIVE\Documents\RFC\rfc1939.txt). 20 Протокол электронной почты SMTP Протокол SMTP (Simple Mail Transfer Protocol) был разработан для обмена почтовыми сообщениями в сети Internet. SMTP не зависит от транспортной среды и может использоваться для доставки почты в сетях с протоколами, отличными от TCP/IP и Х.25. Взаимодействие в рамках SMTP строится по принципу двусторонней связи, которая устанавливается между отправителем и получателем почтового сообщения. При этом отправитель инициирует соединение и посылает запросы на обслуживание, а получатель на эти запросы отвечает. Фактически, отправитель выступает в роли клиента, а получатель - сервера. На рис. 2.1 приведена схема взаимодействия клиента и сервера по протоколу SMTP. Рис. 2.1 - Схема взаимодействия по протоколу SMTP Канал связи устанавливается непосредственно между отправителем и получателем сообщения. При таком взаимодействии почта достигает абонента в течение нескольких секунд после отправки. Обмен сообщениями и инструкциями в SMTP ведется в ASCII-кодах. После установления соединения, как правило, используя 25 порт, клиент должен обязательно отправить на сервер команду HELO <HOST>. Эта команда используется для идентификации машины отправителя (HOST) на SMTP сервере. Следующее командой должна идти команда MAIL, идентифицирующая отправителя: MAIL <SP> FROM: <reverse-path> <CRLF> Пример: MAIL FROM: [email protected] Эта команда указывает SMTP-серверу начать новую транзакцию по приёму почты. В качестве аргумента, она передаёт на сервер почтовый адрес отправителя письма. Если адрес отправителя правильный и не содержит ошибок, то сервер вернёт ответ «250 OK». Следующей командой идёт команда RCPT: RCPT <SP> TO: <forward-path> <CRLF> Пример: RCPT TO: [email protected] Эта команда передаёт на сервер почтовый адрес получателя письма. Если адрес получателя не содержит ошибок, то тогда SMTP сервер вернёт ответ «250 OK». Если в адресе получателя есть ошибка, то сервер вернёт сообщение с кодом 550. Данная команда может повторяться сколь угодно долго по числу получателей, однако современные почтовые сервера вводят ограничения на количество одновременных 21 получателей. Следующей командой идёт команда DATA <CRLF> Если она принимается сервером, то он возвращает сообщение с кодом 354, приглашающее продолжить отправку сообщения. После этого, на сервер можно передавать текст почтового сообщения. Признаком окончания передачи почтового сообщения является символ точки «.» в начале новой строки. Если сообщение принято к доставке, то сервер вернёт уведомление с кодом 250, а иначе – сообщение об ошибке. После принятия сервером сообщения к отправке, клиент должен отправить команду QUIT, которая сигнализирует серверу, что больше отправки писем не будет. После принятия от сервера подтверждения этой команды, следует закрыть соединение с сервером. Пример SMTP диалога, между отправителем (SENDER) и сервером (RECEIVER): SENDER: MAIL FROM: <Smith@Alpha> RECEIVER: 250 OK SENDER: RCPT TO: <Jones@Beta> RECEIVER: 250 OK SENDER: RCPT TO: <Green@Beta> RECEIVER: 550 No such user here SENDER: RCPT TO: <Brown@Beta> RECEIVER: 250 OK SENDER: DATA RECEIVER: 354 Start mail input; end with <CRLF>.<CRLF> SENDER: Blah blah blah... SENDER: ...etc. etc. etc. SENDER: <CRLF>.<CRLF> RECEIVER: 250 OK Протокол электронной почты POP3 РОРЗ (Post Office Protocol v.3) — это простейший протокол для работы пользователя с содержимым своего почтового ящика. Он позволяет только забрать почту из почтового ящика сервера на рабочую станцию клиента и удалить ее из почтового ящика на сервере. Всю дальнейшую обработку почтовое сообщение проходит на компьютере клиента. Многие концепции, принципы и понятия протокола POP выглядят и функционируют подобно SMTP. Команды POP практически идентичны командам SMTP. На рис. 4.2 изображена модель взаимодействия клиента и сервера по протоколу POP. Сервер POP находится между агентом пользователя и почтовыми ящиками. Рис. 2.2 – Конфигурация модели клиент-сервер по протоколу POP3 22 В протоколе РОРЗ оговорены три стадии процесса получения почты: авторизация, транзакция и обновление. После того как сервер и клиент РОРЗ установили соединение, начинается стадия авторизации. На стадии авторизации клиент идентифицирует себя для сервера. Если авторизация прошла успешно, сервер открывает почтовый ящик клиента и начинается стадия транзакции. В ней клиент либо запрашивает у сервера информацию (например, список почтовых сообщений), либо просит его совершить определенное действие (например, выдать почтовое сообщение). Наконец, на стадии обновления сеанс связи заканчивается. Авторизация пользователя. После того как программа установила TCP-соединение с портом протокола РОРЗ (официальный номер 110), необходимо послать команду USER с именем пользователя в качестве параметра. Если ответ сервера будет +ОК, нужно послать команду PASS с паролем этого пользователя: Пример: CLIENT: USER ivan SERVER: +ОК CLIENT: PASS secret SERVER: +ОК ivan's maildrop has 2 messages (320 octets) Последняя строчка ответа означает, что в почтовом ящике ivan есть 2 сообщения (320 байтов). Транзакции РОРЗ. После того как стадия авторизации окончена, обмен переходит на стадию транзакции. В следующих примерах демонстрируется возможный обмен сообщениями на этой стадии. Команда STAT возвращает количество сообщений и количество байтов в сообщениях: CLIENT: STAT SERVER: +ОК 2 320 Команда LIST (без параметра) возвращает список сообщений в почтовом ящике и их размеры: CLIENT: LIST SERVER: +ОК SERVER: 2 messages (320 octets) SERVER: 1 120 SERVER: 2 200 ... Команда LIST с параметром возвращает информацию о заданном сообщении: CLIENT: LIST 2 SERVER: +ОК 2 200 ... CLIENT: LIST 3 SERVER: -ERR no such message, only 2 messages in maildrop Команда TOP возвращает заголовок, пустую строку и первые десять строк тела сообщения: CLIENT: TOP 10 SERVER: +ОК SERVER: <the POP3 server sends the headers of the message, a blank line, and the first 10 lines of the message body> (сервер POP высылает заголовки сообщений, пустую строку и первые десять строк тела сообщения) SERVER: .... CLIENT: TOP 100 SERVER: -ERR no such message Команда NOOP не возвращает никакой полезной информации, за исключением 23 позитивного ответа сервера. Однако позитивный ответ означает, что сервер находится в соединении с клиентом и ждет запросов: CLIENT: NOOP SERVER: +ОК Следующие примеры показывают, как сервер POP3 выполняет действия. Например, команда RETR извлекает сообщение с указанным номером и помещает его в буфер местного UA (почтового агента): CLIENT: RETR 1 SERVER: +OK 120 octets SERVER: <the POPS server sends the entire message here> (РОРЗ-сервер высылает сообщение целиком) SERVER: ...... Команда DELE отмечает сообщение, которое нужно удалить: CLIENT: DELE 1 SERVER: +OK message 1 deleted ... (сообщение 1 удалено) CLIENT: DELE 2 SERVER: -ERR message 2 already deleted (сообщение 2 уже удалено) Команда RSET снимает метки удаления со всех отмеченных ранее сообщений: CLIENT: RSET SERVER: +OK maildrop has 2 (в почтовом ящике 2 сообщения (320 байтов)) messages (320 octets) Как и следовало ожидать, команда QUIT закрывает соединение с сервером: CLIENT: QUIT SERVER: +OK dewey POP3 server signing off CLIENT: QUIT SERVER: +OK dewey POP3 server signing off (maildrop empty) CLIENT: QUIT SERVER: +OK dewey POP3 server signing off (2 messages left) Обратите внимание на то, что отмеченные для удаления сообщения на самом деле не удаляются до тех пор, пока не выдана команда QUIT и не началась стадия обновления. В любой момент в течение сеанса клиент имеет возможность выдать команду RSET, и все отмеченные для удаления сообщения будут восстановлены. Задание на лабораторную работу: Ознакомившись с протоколами SMTP, описанным в RFC 788 и POP3, описанным в RFC 1939 выполнить нижеприведенные задания. Написать приложение: с помощью которого можно отправлять email сообщения. с помощью которого можно принимать email сообщения, оставленные в почтовом ящике. с помощью которого можно просматривать список email сообщений в почтовом ящике и удалять выбранные сообщения. с помощью которого можно просматривать дополнительную информацию о заданном сообщении и удалять выбранные сообщения из почтового ящика. Указанные приложения можно реализовать как в консольном варианте, так и с применением GUI. Для реализации можно использовать Java-Swing, AWT, C# - .Net , C++ QT, Python. 24 3.4 Лабораторная работа №3 Моделирование протоколов канального уровня Основные протоколы канального уровня, рассматриваемые в данной работе, соответствуют стандартным топологиям локальных сетей: звезда, шина и кольцо, им в свою очередь соответствуют такие известные технологии как 100VGAnyLan, Ethernet, Token Ring, FDDI. Ethernet. (самый распространённый стандарт локальных сетей ieee 802.3) Технология ethernet использует метод доступа к среде CSMA/CD — коллективного доступа к несущей и обнаружением коллизий и логической общей шиной, данный метод произошел из радиосетей. Все компьютеры имеют общий доступ к одной среде или шине для передачи данных, все компьютеры могут получать данные из такой среды. Перед отправкой кадра каждый узел сети проверяет занят ли в данный момент канал, анализируя наличие несущей частоты в канале — 5 — 10Мгц, если она присутствует то узел ждет освобождения канала для передачи, если канал свободен, то узел отправляет кадр, после отправки кадра идет 9.5 мкс интервал простоя. Часто в такой сети при интенсивной загрузке возникают коллизии если два узла сразу отправляют кадр обнаружив канал свободным, что искажает кадры и сигналы. Обнаружение коллизии осуществляется всеми узлами, при этом узел обнаруживая коллизию усиливает ее отправляя специальную 32 битовую последовательность. Отправляющий узел зафиксировавший коллизию должен прекратить передачу кадра и осуществить повторную отправку через случайный интервал времени, при повторной коллизии интервал времени выбирается случайным образом из большего диапазона до 54 мс. При нормальной передаче кадр воспринимается всеми узлами, если поле адреса совпадает с получателем, то кадр записывается в буфер узла, затем отправляется ответ узлу отправителю. Технология предусматривает, что в определенных ситуациях коллизия может быть не обнаружена и поврежденный кадр будет принят, когда, например, кадр распространяется быстрее, чем коллизия распространится по всей шине. Для этого приняты соглашения о максимальной длине шины и минимальном размере передаваемого кадра. С одной стороны протоколы верхнего уровня могут решить эту проблему при анализе контрольных сумм, но это внесет дополнительные проблемы со скоростью передачи. Таким образом, принято, что максимальная длина шины 500 м и 2500 м при сегментировании сети повторителями и 576 бит отведено на минимальный кадр. Пропускная способность составляет от 5 до 10 Мбит в сек. Существует четыре вида кадра данной технологии. Кадр стандарта 802.3llc, являющий кадром уровня mac состоит из поля преамбулы 7 байт синхронизирующих бит 10101010 и завершающего 8-го 10101011. Адрес назначения — 2 или 6 байт, Обычно 6 байт, первый старший бит указывает является ли адрес групповым, или индивидуальным. Групповой адрес может предназначаться всем узлам сети или группе, для широковещательного адреса используется последовательность из единичных битов. Второй бит определяет назначен ли адрес централизовано или локально, обычно 0 — централизовано. 22 старших бита кодируют номер компании выдаваемый организаций ieee, остальные три байта даются компании для кодирования своих интерфейсов устройств. Далее адрес источника, 2 или 6 байт, с 0м старшим битом. Далее двубайтовое поле определяющее длину поля данных. Поле данных 0 — 1500 байт. Поле заполнения для обеспечения минимальной длины поля данных 46 байт. Поле контрольной суммы по алгоритмы crc -32, 4 байта. В поле данных данного кадра вкладывается mac подуровня вкладывается llc кадр. Другие три типа кадров усовершенствованы добавлением дополнительного поля type — два байта указывающий протокол более высокого сетевого уровня (напр. IP - 0x0800) (тоже что и sap), причем номера sap и type не совпадают для одного протокола. Также доблавяется дополнительный байт кодирующий номер организации контролирующей номера поля type. Например, ip протокол в сетях ethernet использует как раз такой кадр llc/snap, в сетях fast ethernet, ethernet/dix, только с полем type и без вложения кадра llc. Распознавание типа кадра делается по остаточным битам поля длины поля данных, т.к. максимальная длина данных 1500 байт, остальные биты под тип кадра ethernet. 25 Выработано несколько спецификаций ethernet для различных типов физических сред передачи данных — коаксиальные, витая пара, оптоволокно. 10Base-2, 10Base-5, 10Base-T, 10Base-F, первые основаны на применении коаксиальный кабелей с заглушками на концах проводов, две последние основаны на топологии звезда на основе концентраторов, узел подключается через витую пару ко входу концентратора для передачи сигнала и к выходу концентратора для приема, концентраторы между собой образуют связь и логическое соединение шина. При этом концентраторы могу выстраиваться между собой в иерархическую связь, для обнаружения коллизий должно соблюдаться правило — число концентраторов между двумя узлами не более 4-х или правило четырех хабов. Технология Token Ring (ieee 802.5). Сети Token Ring используют разделяемую среду передачи данных, которая состоит из отрезков кабеля, соединяющих все станции сети в кольцо. Скорость работы сети может быть 4 и 16 Мбит в с. Технология обладает свойством отказоустойчивости. Для контроля сети одна из станций выполняет роль активного монитора, который выбирается во время инициализации кольца как станция с максимальным MAC адресом. Если активный монитор выходит из строя, то процедура инициализации повторяется и выбирается новый активный монитор. Чтобы сеть могла обнаружить отказ активного монитора, он каждые три секунды отправляет специальный кадр своего присутствия. Если этот кадр не появляется более 7 ми секунд, то остальные станции начинаю процедуру выбора активного монитора. Для обеспечения доступа станций к физической среде по кольцу циркулирует кадр специального формата и назначения — маркер. В сети tr любая станция всегда получает данные только от предыдущей в кольце станции — ближайший активный сосед выше по потоку. Передачу данных станция всегда осуществляет своему ближайшему соседу вниз по потоку. Получив маркер, станция анализирует его и при отсутствии у нее данных для передачи обеспечивает его продвижение к следующей станции. Станция, которая имеет данные для передачи, при получении маркера изымает его из кольца, что дает ей право доступа к физической среде. Станция выдает в кольцо кадр данных последовательно по битам. Переданные данные проходят по кольцу всегда в одном направлении от одной станции к другой. Кадр снабжен адресом источника и адресом назначения. Все станции ретранслируют кадр побитно. Если кадр распознан станцией назначения, то она копирует кадр в свой внутренний буфер и вставляет в кадр признак подтверждения приема. Станция, выдавшая кадр данных в кольцо, при обратном его получении с подтверждением приема изымает кадр из кольца и передает в сеть новый маркер. После истечения времени удержания маркера станция обязана прекратить передачу собственных данных, обычно при этом время удержания 10 мс, со скоростью 4 мбит в сек, можно передать 5000 байт 1 или более кадров. Существует процедура раннего освобождения маркера когда станция сразу после передачи последнего бита кадра не дожидаясь подтверждения о приеме кадра станцией назначения, передает маркер доступа другой станции. Для различных видов сообщений кадрам может назначаться приоритет, от 0 (низший) до 7(высший). Станция имеет захватить маркер если она имеет кадры для передачи того же или высшего приоритета чем приоритет маркера, иначе маркер передается следующей станции. За наличие единственного в сети маркера отвечает активный монитор, если активный монитор не получает долго время маркера, он порождает новый. Существует три типа кадров. Кадр маркера состоит из трех полей длиной в 1 байт, сначала идет начальный ограничитель — уникальная последовательность символов манчестерского кода — jk0jk000. Затем управление доступом — с битами приоритета, маркера, монитора и резервных бит. Бит маркера указывает, что данный кадр является маркером, бит монитора устанавливается в 1 монитором и в ноль станциями, монитор тогда знает если маркер был обработан станциями при прохождении кольца. Поле конечного ограничителя — уникальная последовательность jk1jk1, а также бит ошибки и бит того, является ли кадр последним в серии кадров или промежуточным. Кадр данных включает те же три поля и имеет еще несколько дополнительных полей: Начальный ограничитель, управление кадром, адрес назначения, адрес источника, данные, 26 контрольная сумма, конечный ограничитель, статус кадра. Стандарт tr определяет шесть типов управляющих кадров MAC уровня. Для того, чтобы удостовериться, что адрес уникальный станция, когда впервые присоединяется к кольцу, посылает кадр — тест дублирования адреса. Активный монитор чтобы сообщить о своей работоспособности другим станциям периодически отправляет кадр — существует активный монитор. Резервный монитор отправляет кадр маркер заявки, когда подозревает отказ активного монитора. Станция отправляет кадр Сигнал в случае возникновения серьезных сетевых проблем — обрыв кабеля, обнаружения станции отправляющей кадры без получения маркера, выход станции из строя. Кадр очистка используется новым активным монитором для приведения кольца в исходное состояние и очистка от ранее посланных кадров. В данном стандарте используются тот же формат адресов, что и в ethernet. Стандарт tr предусматривает построение сети связей с помощью концентраторов, MSAU (multistation access unit), допускается до 260 узлов сети. Концентратор может работать в режиме простого соединителя, так, чтобы станции при соединении образовывали кольцо и при отключении одного из узлов происходил обход порта данного узла через порт концентратора, также концентратор может быть и повторителем усиливающим сигналы. В общем случае tr имеет комбинированную звезднокольцевую конфигурацию. Конечные узлы подключаются к MSAU по топологии звезды, а сами концентраторы объединяются через специальные порты для образования магистрального физического кольца. Максимальная длина кольца 4000 м. Технология FDDI — оптоволоконный интерфейс распределенных данных, во многом основана на технологии token ring. Позволяет достигать скорости передачи до 100 Мбит в сек. Сеть строится на основе двух оптоволоконных колец, которые образуют основной и резервный пути передачи данных между узлами сети. Максимальный диаметр кольца до 100 км, число машин 500, расстояние между узлами до 2 км. В нормальном режиме работы сети данные передаются через все узлы и все участки кабеля первичного кольца. В случае какого либо отказа, когда часть первичного кольца не может передавать данные, то первичное кольцо объединяется со вторичным образуя единое кольцо, при этом первичное кольцо замыкается на вторичное. При множественных отказах сеть распадается на несколько не связанных сетей. Время удержания маркера в fddi не является постоянной величиной. Механизм приоритетов отсутствует, вводится два класса трафика — синхронный и асинхронный. Синхронный обслуживается всегда, даже при перегрузки сети. Асинхронный может захватить маркер только если тот сделал обход кольца достаточно быстро. В остальном пересылка кадров на уровне mac такая же как и в tr. Станции fddi также используют механизм раннего освобождения маркера. Для передачи световых сигналов по оптическим волокнам реализовано кодирование 4b 5b в сочетании с потенциальным кодом и инверсией при единице. Для ускорения передачи данных была разработана технология fast ethernet позволяющая достигать скорости передачи до 100 Мбит в сек, при этом данная технология наследовала практически все свойства технологии ethernet, оставив метод доступа с коллизиями. Все отличия в основном на физическом уровне, когда используются 4-е пары витой пары 3-й категории или две витые пары 5-й категории, либо два оптоволоконных кабеля. Время передачи минимального кадра уменьшено в 10 раз, диаметр сети сокращен до 200 м. Технология 100VG-AnyLAN использует 4-е витых пары с скоростью передачи в каждой 25 мбит в сек, что в сумме дает 100 мбит в сек. Устранен механизм коллизий. Используется код 5b 6b. В сети используется арбитр доступа — концентратор, который решает проблему доступа к среде. Узлы и концентраторы могут выстраиваться в иерархию из трех уровней, где корнем выступает центральный концентратор. Каждый концентратор должен быть настроен либо на кадры token ring либо ethernet. Концентратор циклически проводит опрос портов. Станция желающая передать кадр посылает специальный низкочастотный сигнал запрашивая передачу кадра и указывая его приоритет — низкий или 27 высокий. Например станция долго не имеющая доступ к сети, получает высокий приоритет, либо высокий приоритет могут иметь мультимедийные данные. Если сеть свободная концентратор разрешает передачу кадра. При этом анализируя адрес получателя сразу отправляет данные по назначению, анализ адресов и маршрутов производится на этапе подключения узлов к сети. Если не свободна то ставит запрос в очередь и обслуживает запрос в соответствии с приоритетами. Если к концентратору подключён другой концентратор, то сначала ожидается когда завершит опрос концентратор на более низком уровне. Решение об обслуживании запроса выполняется после опроса всех концентраторов и портов. Концентратор не может хранить кадры в своем буфере. Gigabit ethernet допускает скорость передачи до 1000 мбит в секунду. Минимальный размер кадра увеличен до 512 байт. Сохраняются все принципы ethernet. Задание на лабораторную работу. Реализовать с помощью соккетов UDP моделирование какой-либо из технологий канального уровня, осуществлять пересылку кадров от узла к узлу. Каждый узел генерирует трафик кадров с заданной интенсивностью через случайные промежутки времени. Каждый из узлов является или отдельным приложением или является частью многопоточного приложения с несколькими клиентами. Промоделировать ситуацию повреждения кадра с какой-то вероятностью. Варианты заданий. 1) Топология шина. Технология Ethernet. Рассмотреть ситуации связанные с коллизиями, вывести на экран количество коллизий и количество переданных кадров, количество полученных кадров. Осуществить расчет минимального размера кадра исходя из диаметра сети и скорости передачи. 2) Топология шина. Технология Ethernet. Осуществить сравнение сети с наличием интеллектуального коммутатора (или моста) и сетью без разбиения на сегменты. Реализовать для этого работу интеллектуального коммутатора. Проверить ситуации связанные с появлением петель. 3) Топология кольцо. Технология Token Ring. Осуществить реализацию выбора системного монитора в случае его потери, для чего случайным образом или по выбору пользователя моделировать данную ситуацию. Осуществить моделирование ситуации потери маркера. 4) Топология кольцо. Технология FDDI. Реализовать выборы системного монитора в случае разрыва кольца, использование резервного кольца в случае разрыва или выхода из строя промежуточного элемента связи. 5) Иерархическая топология (арбитрный доступ). Звезда. Технология 100VGAnyLan. Реализовать работу арбитрного коммутатора, арбитрных коммутаторов соединенных между собой в виде иерархии. Пример клиента и сервера, использующие UDP UDP основывается на протоколе без установления соединений, то есть протокол, не гарантирующий доставку информации. UDP-пакеты могут приходить не в указанном порядке, дублироваться и приходить более одного раза, или даже не доходить до адресата вовсе. Из-за этих минимальных гарантий, UDP значительно уступает протоколу TCP. Отсутствие установки соединений означает отсутствие потоков или соединений между двумя хостами, так как вместо этого данные прибывают в датаграммах (Датаграммный сокет). Адресное пространство UDP, область номеров UDP-портов (в терминологии ISO — TSAP) полностью отделены от TCP-портов. Сервер 28 Код может создавать UDP-сервер на порту 7654 следующим образом: int sock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); struct sockaddr_in sa; int bound; ssize_t recsize; socklen_t *address_len=NULL; sa.sin_addr.s_addr = htonl(INADDR_ANY); sa.sin_port = htons( 7654 ); bound = bind( sock, ( struct sockaddr* )&sa, sizeof( struct sockaddr ) ); if ( bound < 0 ) fprintf( stderr, "bind(): ошибка %s\n", strerror( errno ) ); //bind() связывает сокет с парой адрес/порт. while( 1 ) { printf( "recv test....\n" ); recsize = recvfrom( sock, ( void* )Hz, 100, 0, ( struct sockaddr* )&sa, address_len ); if ( recsize < 0 ) fprintf( stderr, "Ошибка %s\n", strerror( errno ) ); printf( "recsize: %d\n ", recsize ); sleep( 1 ); printf( "datagram: %s\n", Hz ); } Такой бесконечный цикл получает все UDP-датаграммы, приходящие на порт 7654, при помощи recvfrom(). Функция использует параметры: Клиент Простейшая демонстрация отправки UDP-пакета, содержащего «Привет!» на адрес 127.0.0.1 порт 7654 выглядит примерно так: #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <unistd.h> /* для вызова close() для сокета */ int main( void ) { int sock; 29 struct sockaddr_in sa; int bytes_sent; const char* buffer = "Привет!"; int buffer_length; buffer_length = strlen( buffer ) + 1; sock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); if ( sock == -1 ) { printf("Ошибка создания сокета"); return 0; } sa.sin_family = PF_INET; sa.sin_addr.s_addr = htonl( 0x7F000001 ); sa.sin_port = htons( 7654 ); bytes_sent = sendto( sock, buffer, strlen( buffer ) + 1, 0, ( struct sockaddr* )&sa, sizeof( struct sockaddr_in ) ); if ( bytes_sent < 0 ) printf( "Ошибка отправки пакета: %s\n", strerror( errno ) ); close( sock ); return 0; } 3.5 Лабораторная работа №4 Браузер и FTP-клиент Лабораторная работа №3 выполняется после изучения материала, посвященного описанию принципов использования стандартных компонентов Delphi, Visual C++ или Java, для управления соединениями с сервером по протоколам HTTP и FTP. Цель работы: написать GUI приложение для ОС Windows, представляющее собой простой Web – браузер и FTP – клиент, используя стандартные компоненты Delphi, Visual C++, Java Рекомендуемая литература: Компьютерные сети. 4-е издание / Э. Таненбаум. – Спб.: Питер, 2003. – 992 с.: ил. Глава 7 («Прикладной уровень») раздел «HTTP – протокол передачи гипертекста». Описание протокола HTTP в спецификации RFC-2616 (ARCHIVE\Documents\RFC\rfc2616.txt). Описание протокола FTP в спецификации RFC-959 (ARCHIVE\Documents\RFC\rfc0959.txt). 30 На различных платформах и в языках программирования предусмотрены стандартные классы для работы с сетью. Например, в состав библиотеки MFC (Microsoft Foundation Classes – библиотека базовых классов) включено большое количество классов, с помощью которых можно писать как клиентские, так и серверные приложения. В частности, для связи с Internet в Visual C++ существует так называемый WinInet Class. В него входят несколько подклассов. Задание на лабораторную работу Следует создать сетевое приложение на любом из перечисленных языков. 1. Браузер HTML. Создать на любом из трех языков программирования (C++, Delphi, Java, С#) простой Web-браузер. С установленного ранее Web- сервера запросите и получите Web-страницу с рисунками, текстом и ссылками. Ссылки должны работать, то есть щелчок мышью по ссылке вызывает загрузку и отображение соответствующей страницы. У браузера должна быть адресная строка, в которую заносится адрес URL. 2. FTP - клиент. Создать на любом из трех языков программирования (C ++, Delphi, Java, C#) простое приложение-клиент для работы по протоколу FTP. Приложение должно обеспечивать соединение с сервером, передачу имени пользователя и пароля, отображение списка каталогов и файлов, навигацию по каталогам, копирование файла или каталога на сторону клиента. У приложения клиента должны быть текстовые поля для ввода имени сервера, пользователя, пароля, объект для отображения содержимого каталогов, кнопка для копирования, и удаления каталогов и файлов. 3.6 Лабораторная работа №5. HTML, Javascript технология PHP HTML и Javascript Лабораторная работа выполняется после изучения основ Web – программирования на языке HTML и JavaScript. Цель работы: Научиться использовать технологии HTML, JavaScript, PHP для создания простых Web - страниц со статическим содержанием Материалы: 1. Материалы лекций, 2. http: //ru.wikipedia.org/wiki/ – элементы HTML. 3. http: //ru.wikipedia.org/wiki/JavaScript - JavaScript В таблице дан список файлов и описание электронной документации прилагаемой в архиве. Инструменты: Текстовый редактор Web - браузер Internet Explorer Структура HTML-документа HTML — это теговый язык разметки документов, то есть любой документ на языке HTML представляет собой набор элементов, причем начало и конец каждого элемента обозначается специальными пометками, называемыми тегами. Регистр, в котором набрано имя тега, в HTML значения не имеет. Элементы могут быть пустыми, то есть не содержащими никакого текста и других данных (например, тег перевода строки <br>). В этом случае обычно не указывается закрывающий тег. Кроме того, элементы могут иметь атрибуты, определяющие какие-либо их свойства (например, размер шрифта для тега <font>). Атрибуты указываются в открывающем теге. Вот пример части разметки HTML- документа: <p>Текст между двумя тегами - открывающим и закрывающим.</p> <a href="http: //www.example.com">Здесь элемент содержит атрибут href.</a> А вот пример пустого элемента: <br> Каждый HTML-документ, отвечающий спецификации HTML какой- либо версии, обязан начинаться со строки декларации версии HTML <! DOCTYPE>, которая обычно 31 выглядит примерно так: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01// EN" "http: //www.w3.org/TR/html4/strict.dtd"> Если эта строка не указана, то добиться корректного отображения документа в браузере становится труднее. Далее обозначается начало и конец документа тегами <html> и </html> соответственно. Внутри этих тегов должны находиться теги заголовка (<head></head>) и тела (<body></body>) документа. Основные элементы HTML – документа Теги и их параметры нечувствительны к регистру. То есть <A HREF = http: //yahoo.com> и <a href = http: //yahoo.com> означают одно и то же. В последних версиях HTML практически у каждого тега огромное число необязательных параметров — обычно не меньше 15. Мы приводим только основные параметры тегов. Гиперссылки <A HREF=url > гиперссылка </A> — гиперссылка. Текстовые блоки <H1> … </H1>, <H2> … </H2>, … ,<H6> … </H6> — заголовки 1, 2, … 6 уровня: <P> — новый параграф. Можно в конце параграфа поставить </P>, но это не обязательно; <BR> — новая строка. Этот тег не закрывается (то есть не существует тега </BR>; <HR> — горизонтальная линия; <BLOCKQUOTE> … </BLOCKQUOTE> — цитата. Обычно текст сдвигается вправо; <PRE … </PRE> — режим preview. В этом режиме текст заключается в рамку и никак не форматируется (то есть теги, кроме </PRE>, игнорируются, и переводы строки ставятся там, и только там, где они есть в оригинальном документе); <DIV> … </DIV> — блок (обычно используется для применения стилей CSS); <SPAN> … </SPAN> — строка (обычно используется для применения стилей CSS). Форматирование текста <EM> … </EM> — логическое ударение (обычно отображается курсивным шрифтом); … </STRONG> — усиленное логическое ударение (обычно отображается жирным шрифтом); <I> … </I> — выделение текста курсивом; <B> … </B> — выделение текста жирным шрифтом; <U> … </U> — подчёркивание текста; <S> … </S> — зачёркивание текста; <BIG> … </BIG> — увеличение шрифта; <SMALL> … </SMALL> — уменьшение шрифта; <BLINK> … </BLINK> — мигающий текст. Это один из самых ненавидимых тегов, потому что мигающий текст неприятен для глаз; <MARQUEE> … </MARQUEEK> — сдвигающийся по экрану текст. Степень народной любви к этому тэгу примерно такая же, как и к мигающему; <SUB> … </SUB> — подстрочный текст. Например, H<SUB>2</SUB>O создаст текст H2O; <SUP> … </SUP> — надстрочный текст. Например, E=mc<SUP>2</SUP> создаст текст E=mc2; <FONT параметры> … </FONT> — задание параметров шрифта. <STRONG> Списки <UL> <LI> первый элемент </LI> <LI> второй элемент </LI> <LI> третий элемент </LI> </UL> создаёт список: первый элемент второй элемент третий элемент Если вместо <UL> (Unordered List, что означает ненумерованный список) поставить 32 <OL> (Ordered List, нумерованный список), список получится нумерованным: первый элемент второй элемент третий элемент Объекты <IMG SRC=имя или URL> — вставка изображения. Этот тег не закрывается; <APPLET>…</APPLET> — вставка Java-апплетов; <SCRIPT>…</SCRIPT> — вставка скриптов; Таблицы — создание таблицы. Параметры тега: BORDER — толщина разделительных линий в таблице; CELLSPACING — расстояние между клетками; CAPTION — заголовок таблицы (этот тег необязателен); TR — строка таблицы; TH — заголовок столбца таблицы (этот тег необязателен); TD — ячейка таблицы; height - высота таблицы; <TABLE>…</TABLE> Так, например, код: <TABLE BORDER="1" CELLSPACING="0"> <CAPTION> Улов крокодилов </CAPTION> <TH> Год </TH> <TH> Улов </TH> <TR> <TD> 1997 </TD> <TD> 214 </TD> </TR> <TR> <TD> 1998 </TD> <TD> 216 </TD> </TR> <TR> <TD> 1999 </TD> <TD> 207 </TD> </TR> </TABLE> <FORM> — создание формы <INPUT> — элемент ввода (может иметь разные функции — от ввода текста до отправки формы) <TEXTAREA> — текстовая область (многострочное поле для ввода текста) <SELECT> — список (обычно в виде выпадающего меню) <OPTION> — пункт списка JavaScript JavaScript — интерпретируемый язык программирования, являющийся одной из реализаций языка ECMAScript и основанный на концепции прототипов, пришедшей из языка Self. В настоящее время JavaScript используется в основном для создания сценариев поведения браузера, встраиваемых в Web-страницы, но также находит применение в качестве скриптового языка доступа к объектам приложений. Некоторые приложения имеют встроенный интерпретатор JavaScript, позволяющий расширять их возможности без изменения самого приложения. JavaScript обладает рядом свойств объектно-ориентированного языка, но благодаря прототипированию поддержка объектов в нём отличается от традиционных объектноориентированных языков. Так же, JavaScript имеет ряд свойств, присущих функциональным языкам — функции как объекты первого уровня, объекты как списки, карринг (currying), анонимные функции, замыкания (closures) — что придаёт языку дополнительную гибкость. Название JavaScript является зарегистрированной торговой маркой компании Sun Microsystems, Inc. О языке JavaScript Синтаксис JavaScript хотя и похож на язык Си, концептуально имеет коренные отличия. Основными чертами JavaScript являются: функции как объекты первого уровня обработка исключений автоматическое приведение типов автоматическая сборка мусора анонимные функции Изначально JavaScript был разработан как скриптовый язык для расширения возможностей существующих приложений. В первую очередь он стал хорошо известным и популярным благодаря использованию в браузерах. При использовании в рамках технологии DHTML, код JavaScript включается в HTMLкод страницы и исполняется интерпретатором, встроенным в браузер. JavaScript заключается в теги <script></script>, по спецификации HTML 4.01 у тега <script> обязателен атрибут 33 type="text/javascript", хотя в большинстве браузеров язык сценариев по умолчанию именно JavaScript. При этом атрибут language (language="JavaScript"), несмотря на его активное использование, не входит в стандарт и поэтому считается некорректным. Примеры программ на JavaScript Пример объявления и использования класса в JavaScript (класс является одновременно функцией, так как фунции - это объекты первого уровня): function MyClass() { this.myValue1 = 1; this.myValue2 = 2; } var mc = new MyClass(); mc.myValue1 = mc.myValue2*2; Скрипт, выводящий модальное окно с классической надписью «Hello, World!» внутри браузера: <script type="text/javascript"> alert('Hello, World!'); </script> Следуя концепции интеграции JavaScript в существующие системы, браузеры поддерживают включение скрипта, например, в значение атрибута события: <a href="delete.php" onclick="return confirm('Вы уверены?'); ">Удалить</a> Здесь при нажатии на ссылку функция alert('Вы уверены?'); вызвает модальное окно с надписью «Вы уверены?», а return false; блокирует переход по ссылке. Разумеется, этот код будет работать только если в браузере есть и включена поддержка JavaScript, иначе переход по ссылке произойдет без предупреждения. Есть и третья возможность подключения JavaScript — написать скрипт в отдельном файле, а потом подключить его с помощью конструкции <script type="text/javascript" src="http://Путь_до_файла_со_скриптом"></script> Задание на лабораторную работу Требуется создать HTML - страницу с внедренным скриптом на языке JavaScript, реализующим некоторый сценарий (в соответствии со своим вариантом). Сценарии даны ниже, в разделе «Варианты». Обязательные требования к каждому сценарию: 1. Вывести в строке статуса часы, показывающие текущее время в формате чч:мм:сс. 2. При движении мыши по странице выводить в строке статуса текущие координаты указателя мыши по вертикали и горизонтали 3. Скрипт должен осуществлять проверку корректности введенных значений, выводить при необходимости окна с сообщениями о неправильных значениях и очищать после этого поле ввода, содержащее ошибку. 4. Расположить страницу локально, например, в домашнюю директорию «test1.ru» под именем index.html, и протестировать работу с помощью браузера. Запрещено использовать какие либо CASE-средства и программы- построители HTML, например: MS Word, FrontPage и т.д. Все содержимое файлов должно быть сверстано вручную в простом текстовом редакторе. При использовании автоматизированных средств контрольные работы приниматься не будут. Ограничение на размер файла HTML – 1Кб. Суммарный объем рисунков 200Кб. Далее приведены варианты заданий. Варианты: Калькулятор: Создать форму, позволяющую осуществлять основные четыре арифметических 34 действия. Должны быть поля для ввода аргументов и поле для вывода результата. Между полями аргументов должен быть выпадающий список, предоставляющий выбор одного из четырех арифметических действий. Также должно быть четвертое поле, в которое вводится предполагаемое значение результата. Если поле заполнено, то скрипт должен сверить полученный результат и вывести сообщение «Верно!» или «Неверно!» в зависимости от правильности результата. Конвертер валют и физических величин: Создать форму позволяющую переводить километры в мили, метры в футы, килограммы в фунты и наоборот (рис. 4.4). Также должен осуществляться пересчет различных валют по курсу. Например, американские доллары в японские иены, рубли в индийские рупии и т.д. Должно быть не менее десяти различных величин или валют. Выбор величин должен сопровождаться выпадающим списком. «Знаете ли Вы HTML»: Создайте скрипт, задающий 5-10 вопросов о тегах и атрибутах HTML (рисунок 4.5). Вопросы должны делиться на две группы: выбор из существующих вариантов (выпадающий список) и открытые вопросы, допускающие ответ в открытом виде (просто текст). Затем скрипт должен проверить правильность и выдать процент успешных ответов. Создайте форму, на которой разместите несколько чек-боксов (кнопка- флажок с независимой фиксацией). Каждый элемент должен сопровождаться текстовой строкой представляющей собой ссылку на некоторую страницу Интернет. Когда пользователь отмечает чек-бокс, то строка, соответствующая чекбоксу автоматически записывается в текстовое поле на странице. После нажатия кнопки «Ок» скрипт должен открыть несколько окон в браузере в соответствии с выбранными ссылками. Это могут быть страницы, размещенные на веб- сервере Apache, в других сайтах test2.ru и т.д. Можно создать свои собственные размещения сайтов. О том, как это сделать смотрите описание пакета Denwer. Фото-галерея: Создать страницу со скриптом, который отображает в зависимости от действий пользователя (нажатие на кнопку) несколько (не более 5-10) различных рисунков попеременно в одной и той же области HTML- страницы (рис. 4.7). Если пользователь выбирает кнопку «Все на одной странице», то скрипт должен открыть новую страницу, на которой должны быть размещены все рисунки в компактном виде. Технология PHP Требуется создать клиент-серверную приложение, взаимодействующее с пользователем с применением технологий HTML и PHP. Основной сценарий, такой же, как в лабораторной работе №7, но вычислительная часть должна располагаться на сервере, генерация страниц должна происходить на серверной стороне, на основе PHP- скриптов. Инструментарий: Любой текстовый редактор Веб-сервер Apache в составе пакета Denwer в локальном каталоге С:\WebServers Скрипты размещаются в подкаталогах home/localhost и т.п. Документация по php находится на диске в файле php_manual_ru.chm Введение в PHP PHP (Hypertext Preprocessor – гипертекстовый препроцессор) - это широко используемый язык программирования общего назначения с открытым исходным кодом. PHP сконструирован специально для ведения Web-разработок и может внедряться в HTML-код. Ниже приведен простой пример программирования на PHP: <html> <head> <title>Пример</title> </head> 35 <body> <?php echo "Привет, я - скрипт PHP!";?> </body> </html> Обратите внимание на отличие этого скрипта от скриптов, написанных на других языках, например, на Perl или C - вместо того, чтобы создавать программу, которая занимается формированием HTML-кода и содержит бесчисленное множество предназначенных для этого команд, вы создаете HTML-код с несколькими внедренными командами PHP (в приведенном случае, предназначенными для вывода текста). Код PHP отделяется специальными начальным и конечным тегами, которые позволяют процессору PHP определять начало и конец участка HTML-кода, содержащего PHP-скрипт. Существует четыре набора тегов, которые могут быть использованы для обозначения PHP-кода. Из них только два (<?php. . .?> и <script language = "php">……… </script>) всегда доступны; другие могут быть включены или выключены в конфигурационном файле php.ini. Теги, поддерживаемые PHP: 1. <?php echo("если вы хотите работать с документами XHTML делайте так\n");?> 2. <? echo ("это простейшая инструкция обработки SGML\n");?> <?= выражение ?> Это синоним для "<? echo выражение ?>" или XML, language="php"> редакторы (например, FronPage) обработки”); </script> 3. <script echo ("некоторые не любят инструкции 4. <% echo ("Вы можете по выбору использовать теги в cтиле ASP");%> <%= $variable;# Это синоним для "<% echo . . ." %> Первый способ, <?php. . .?>, наиболее предпочтительный, так как он позволяет использовать PHP в коде, соответствующем правилам XML, таком как XHTML. Работа с формами Одно из главнейших достоинств PHP - то, как он работает с формами HTML. Здесь основным является то, что каждый элемент формы автоматически становится доступен вашим программам на PHP. Для подробной информации об использовании форм в PHP читайте раздел " Переменные из внешних источников" [Руководства по PHP]. Ниже приведен пример формы HTML: <form action="action.php" method="POST"> Ваше имя: <input type="text" name="name" /> Ваш возраст: <input type="text" name="age" /> Ваш пол: <input type = “radio” name = “gender” CHEKED VALUE = “1”>Мужчина <br> <input type = “radio” name = “gender” VALUE = “2”>Женщина <input type="submit"> </form> В этой форме нет ничего особенного. Это обычная форма HTML без каких-либо специальных тегов. Когда пользователь заполнит форму и нажмет кнопку отправки, будет вызвана страница action.php. В этом файле может быть что-то вроде: Здравствуйте, <?php echo $_POST["name"];?>. <br> Вам <?php echo $_POST["age"];?> лет. <br> Вы <?php if ($_POST["gender"] = 1) {?> Мужчина. <?php } else {?> Женщина. <?php } ?> Пример вывода данной программы: Здравствуйте, Владимир. 36 Вам 30 лет. Вы мужчина. работа данного кода проста и понятна. Переменные $_POST["name"] и $_POST["age"] автоматически установлены для вас средствами PHP. В переменной $_POST["gender"] находится значение VALUE, в зависимости от выбранного переключателя (аналогично можно передавать значения элементов флажков, но при этом значения их атрибута «name» должны отличаться). Заметим, что метод отправки нашей формы - POST. Если бы мы использовали метод GET, то информация нашей формы была бы в суперглобальной переменной $_GET. Также можно использовать переменную $_REQUEST, если источник данных не имеет значения. Эта переменная содержит смесь данных GET, POST, COOKIE и FILE. Варианты: 1. Клиент-серверный вычислитель: Реализовать сценарий 1 лабораторной работы №7 с некоторыми изменениями. На странице HTML должна использоваться форма, принимающая данные от пользователя и отправляющие их на Web-сервер, где выполняются вычисления, и ответ отправляется на сторону клиента в виде автоматически сформированной HTML-страницы. Никакие вычисления на стороне клиента выполняться недолжны. 2. Клиент-серверный конвертер величин: Реализовать сценарий 2 лабораторной работы №7 с некоторыми изменениями. На странице HTML должна использоваться форма, принимающая данные о величине сумм от пользователя и отправляющие их на Web-сервер, где выполняется конвертирование валют, а ответ отправляется на сторону клиента в виде автоматически сформированной HTMLстраницы. Никакие вычисления на стороне клиента выполняться недолжны. 3. Клиент-серверное тестирование: В задании 3 лабораторной работы №7 есть один минус с точки зрения безопасности. Так как javascript является частью пересылаемой клиенту страницы, то тестируемый субъект может узнать ответы из исходного кода страницы. Поэтому, необходимо реализовать клиент-серверное приложение, в котором клиентская часть только отображает вопросы и фиксирует ответы, пересылая их на сервер. На сервере происходит обработка ответов, подсчет правильных и неправильных, и выставляется итоговая оценка. 4. Обновление списка ссылок: Видоизменить сценарий 4 лабораторной работы №7 со следующим образом: пусть сервер меняет набор ссылок в зависимости от того, какой по счету пользователь на сервере. После того как клиент осуществил выбор, весь список выбранных ссылок (или уникальных номеров) должен отправляться на сервер, где сервер автоматически генерирует страницу под заголовком: «Вами были выбраны следующие ссылки:». В теле страницы должны отображаться выбранные клиентом строки. 5. Фото-галерея: Сценарий полностью соответствует варианту 5 лабораторной работы №7, только действия пользователя (щелчки мышью на кнопках или ссылках) передаются серверу, на котором формируется HTML страница с соответствующим рисунком и отправляется обратно клиенту. 3.7 Лабораторная работа № 6. Технология XML Лабораторная работа №5 выполняется после знакомства со стандартами расширяемого языка разметки XML и основами программирования на Java. Цель работы: Овладеть навыками работы с XML и родственными технологиями в Java. 37 Материалы: Данная лабораторная работа опирается на материалы лекций, оригинальное руководство корпорации Sun - j2eetutorial14 (англ.) (установлено локально на каждом компьютере в каталоге C: \Sun\j2eetutorial14\doc ), а также на описание библиотеки xalan в виде javadoc (разархивировать самостоятельно). j2eetutorial14 http: //ru.wikipedia.org/wiki/XML - XML Инструменты: Любая среда разработки на Java Примеры исходного кода, подготовленного к компиляции и сборке: Archive\Documents\Java\j2eetutorial14\examples Библиотека xalan в каталоге с данным описанием лабораторной работы Ресурсы сайта citforum.ru: Язык XML практическое введение. Часть 1 http://www.citforum.ru/internet/xml/index.shtml Язык XML практическое введение. Часть 2 http://www.citforum.ru/internet/xml2/index.shtml Предварительная подготовка : Следует настроить систему для работы с JDK (если это не было сделано ранее). Скопировать библиотеку xalan на локальную машину, разархивировать и подключить к проекту на Java или прописать местоположение библиотеки в classpath Введение в XML XML (Extensible Markup Language — расширяемый язык разметки) — рекомендованный Консорциумом Всемирной паутины язык разметки, фактически представляющий собой свод общих синтаксических правил. XML предназначен для хранения структурированных данных для обмена информацией между программами, а также для создания на его основе более специализированных языков разметки (например, XHTML), иногда называемых словарями. XML является упрощённым подмножеством языка SGML. Целью создания XML было обеспечение совместимости при передаче структурированных данных между разными системами обработки информации, особенно при передаче таких данных через Интернет. Словари, основанные на XML (например, RDF, RSS, MathML, XHTML, SVG), сами по себе формально описаны, что позволяет программно изменять и проверять документы на основе этих словарей, не зная их семантики, то есть не зная смыслового значения элементов. Важной особенностью XML также является применение так называемых пространств имён (англ. namespace). Краткий обзор синтаксиса XML Ниже приведён пример простого кулинарного рецепта, размеченного с помощью XML: <?xml version="1.0" encoding="UTF-8"?> <Recipe name="хлеб" prep_time="5 мин" cook_time="3 час"> <title>Простой хлеб</title> <ingredient amount="3" unit = "стакан"> Мука </ingredient> <ingredient amount="0.25" unit = "грамм"> Дрожжи </ingredient> <ingredient amount = "1.5" unit = "стакан"> Тёплая вода </ingredient> <ingredient amount="1" unit="чайная ложка"> Соль</ingredient> <Instructions> <step>Смешать все ингредиенты и тщательно замесить.</step> <step>Закрыть тканью и оставить на один час в тёплом помещении.</step> <step>Замесить ещё раз, положить на противень и поставить в духовку.</step> </Instructions> </Recipe> Обратите внимание, что названия и значения элементов и атрибутов могут состоять не только из букв латинского алфавита, но десятичным разделителем может быть только точка. Первая строка XML-документа называется объявлением XML (англ. XML declaration) 38 — это необязательная строка, указывающая версию стандарта XML (обычно это 1.0), также здесь может быть указана кодировка символов и внешние зависимости. Остальная часть этого XML-документа состоит из вложенных элементов, некоторые из которых имеют атрибуты и содержимое. Элемент обычно состоит из открывающего и закрывающего тегов (меток), обрамляющих текст и другие элементы. Содержимым элемента (англ. content) называется всё, что расположено между открывающим и закрывающим тегами, включая текст и другие (вложенные) элементы. Ниже приведён пример XML-элемента, который содержит открывающий тег, закрывающий тег и содержимое элемента: <step>Замесить ещё раз, положить на противень и поставить в духовку.</step> Кроме содержания у элемента могут быть атрибуты — пары имя- значение, добавляемые в открывающий тег после названия элемента. Значения атрибутов всегда заключаются в кавычки (одинарные или двойные), одно и то же имя атрибута не может встречаться дважды в одном элементе. Не рекомендуется использовать разные типы кавычек для значений атрибутов одного тега. <ingredient amount="3" unit = "стакан">Мука </ingredient> В приведённом примере у элемента «ingredient» есть два атрибута: «amount», имеющий значение «3», и «unit», имеющий значение «стакан». С точки зрения XML-разметки, приведённые атрибуты не несут никакого смысла, а являются просто набором символов. Кроме текста элемент может содержать другие элементы: <Instructions> <step>Смешать все ингредиенты и тщательно замесить.</step> <step>Закрыть тканью и оставить на один час в тёплом помещении.</step> <step>Замесить ещё раз, положить на противень и поставить в духовку.</step> </Instructions> В данном случае элемент «Instructions» содержит три элемента «step». XML не допускает перекрывающихся элементов. Например, приведённый ниже фрагмент некорректен, так как элементы «em» и «strong» перекрываются. <!-- ВНИМАНИЕ! Некорректный XML! --> <p>Обычный <em>акцентированный <strong>выделенный и акцентированный</em> выделенный</strong> </p> Каждый XML-документ должен содержать в точности один корневой элемент (англ. root element или document element), таким образом, следующий фрагмент не может считаться корректным XML-документом. <!-- ВНИМАНИЕ! Некорректный XML! --> <thing>Cущность №1</thing> <thing>Cущность №2</thing> Для обозначения элемента без содержания, называемого пустым элементом, допускается применять особую форму записи, состоящую из одного тега, в котором после имени элемента ставится косая черта. Следующие фрагменты полностью равнозначны: <foo></foo> <foo/> В XML определены два метода записи специальных символов: ссылка на сущность и ссылка по номеру символа. Сущностью (англ. entity) в XML называются именованные данные, обычно текстовые, в частности спецсимволы. Ссылка на сущность (англ. entity references) указывается в том месте, где должна быть сущность и состоит из амперсанда («&»), имени сущности и точки с запятой («;»). В XML есть несколько предопределённых сущностей, таких как «lt» (ссылаться на неё можно написав «&lt;») для левой угловой скобки и «amp» (ссылка — «&amp;») для амперсанда, возможно также определять собственные сущности. Помимо записи с помощью сущностей отдельных символов, их можно использовать для записи часто встречающихся 39 текстовых блоков. Ниже приведён пример использования предопределённой сущности для избегания использования знака амперсанда в названии: <company-name>AT&amp; T</company-name> Полный список предопределённых сущностей состоит из &amp; («&»), &lt; («<»), &gt; («>»), &apos; («'»), и &quot; («"») — последние две полезны для записи разделителей внутри значений атрибутов. Определить свои сущности можно в DTD-документе. Иногда бывает необходимо определить неразрывный пробел, который в HTML обозначается как &nbsp; в XML его записывают &#160; Ссылка по номеру символа (англ. numeric character reference) выглядит как ссылка на сущность, но вместо имени сущности указывается символ # и число (в десятичной или шестнадцатеричной записи), являющееся номером символа в кодовой таблице Юникод. Амперсанд может быть представлен следующим образом: <company-name>AT&#038; T</company-name> Существует ещё множество правил, касающихся составления корректного XMLдокумента, но целью данного краткого обзора было лишь показать основы, необходимые для понимания структуры XML- документа. Задание на лабораторную работу Задание состоит из следующих частей: ознакомительная (общая часть), и индивидуальная (по вариантам). Необходимо выполнить обе части и результат представить в виде исходного кода с описанием. Общая часть: Необходимо найти описание перечисленных ниже примеров в j2eetutorial14, создать проекты с исходным кодом на Java из этих примеров, откомпилировать проект и запустить на выполнение, проконтролировав результат. Необходимо объяснить суть примера: какие библиотеки используются и их назначение, каков должен быть ожидаемый результат. Список примеров: Document Object Model, Reading XML Data into a DOM (стр.188-194 j2eetutorial14) Document Object Model, Displaying a DOM Hierarchy (стр.195-211 j2eetutorial14) Constructing a User-Friendly JTree from a DOM (стр.221-237 j2eetutorial14) Extensible Stylesheet Language Transformations, Writing Out a DOM as an XML File (стр.253-272 j2eetutorial14) Transforming XML Data with XSLT, Writing the Basic Program (стр.287 -297 j2eetutorial14) Transforming from the Command Line with Xalan (стр.311 j2eetutorial14) Индивидуальная часть: 1. Создать XML-файл, содержащий данные из определенной предметной области (по вариантам). Количество уровней вложенности - не менее 4 (вместе с корневым узлом). По крайней мере у двух разных уровней узлов должны быть атрибуты. Пример на основе классификации живых организмов дан в файле primer.xml в каталоге с данным описанием на диске. Также смотрите пример преобразования XSLT в файлах transform.xsl и module.xml module.xml. Это преобразование извлекает все узлы с именем par вне зависимости от вложенности и выводит их текстовое содержимое на экран с новой строки. Затем извлекает все узлы содержащие комментарии и выводит их следом за блоком параметров. Предметные области (варианты): 40 1.1. Экономика; 1.2. Содержание издания; 1.3. Вычислительная техника; 1.4. Медицина; 1.5. Спорт; 1.6. Детские игрушки и игры; 1.7. Транспорт; 1.8. Военная техника; 1.9. Химия; 1.10. Астрономия; 1.11. Элементарные частицы; 1.12. Мебель; 1.13. Литература; 1.14. Архитектура; 1.15. Изобразительное искусство; 1.16. Оптические приборы; 1.17. Осветительные приборы; 1.18. Одежда; 1.19. Музыка; 1.20. Музыкальные инструменты; 1.21. Типы поверхности Земли; 1.22. Погода. 2. Создать на языке Java приложение, отображающее структуру xml файла в виде дерева JTree; 3. Разработать xsl таблицу позволяющую выводить на экран и в файл содержимое всех узлов в виде текста; 4. Разработать xsl таблицу позволяющую выводить на экран и в файл содержимое всех узлов в виде html (таблица или список по выбору); 5. Продемонстрировать работу созданных в п.3 и 4 xsl таблиц в командной строке xalan; 6. Разработать средство поиска текста по заданному ключу (начало слова) и/или атрибуту в xml файле с помощью XPathAPI библиотеки Xalan. Включить это средство поиска в приложение, созданное в п.2. 3.8 Лабораторная работа №7 Маршрутизация в ВС Лабораторная работа №7 выполняется после ознакомления основными алгоритмами маршрутизации в глобальной сети. Цель работы: Моделирование протоколов маршрутизации в вычислительных сетях. Задание на лабораторную работу Напишите программу, моделирующую один из вариантов: 1) Маршрутизацию методом заливки; 2) Маршрутизацию по вектору расстояния; 3) Маршрутизацию по состоянию связей; 4) Групповая маршрутизация. Остовые деревья (Spanning Trees) 5) Групповая маршрутизация. RPF (Reverse Path Forwarding). 6) Групповая маршрутизация. RPF (Reverse Path Forwarding). С усечением (prunes). 7) Групповая маршрутизация. RPF (Reverse Path Forwarding). С наращением (grant). 8) Групповая маршрутизация. CBT (Core Based Trees, Деревья с фиксированным ядром) 41 9) Групповая маршрутизация методом заливки. Общие требования: Программа должна обладать следующими возможностями: Графический интерфейс. Возможность вводить ненаправленный граф (входное дерево сети) в виде: A B <cost>, где A – имя маршрутизатора, для которого формируется запись; B – имя узла, с которым есть соединение; <cost> значение стоимости данного соединения в условных единицах (word); Ввод можно осуществлять из файла или вручную. Количество узлов в сети не менее 10; Возможность просматривать таблицу маршрутизации для каждого узла, если таковая имеется; Возможность обозначать начальный и конечный узел сети; Индикация решения (оптимального пути на графе в виде последовательности вершин и суммарной стоимости пути) для заданных в п.4 вершин; Возможность динамически добавлять и удалять узлы маршрутизаторов на существующей сети Демонстрировать для добавленных узлов пошаговое формирование таблиц маршрутизации; Демонстрировать, как меняется таблица маршрутизации соседнего узла если некоторый смежный узел был удален; Для метода заливки показать пошаговое распространение пакетов оценить количество лишних – дублированных пакетов; Для метода вектора расстояния продемонстрировать возникновение счета до бесконечности при удалении узла; Для метода состояния связей продемонстрировать, как влияет динамическое изменение стоимости связи на принимаемые решения о маршрутизации; Для алгоритмов групповой маршрутизации добавить возможность подсоединения узлов в групповой рассылке или данному групповому адресу. Реализовать возможность нескольких групповых адресов. Теория. Для маршрутизации применяются специальные алгоритмы и протоколы (например, RIP, OSPF, NLSP). C помощью протоколов маршрутизации создается карта сети или специальные таблицы маршрутизации, которые хранятся на каждом маршрутизаторе. Одношаговые алгоритмы маршрутизации определяют только следующий маршрутизатор в сети для отправки пакета, каждый маршрутизатор ответственен за выбор одного шага маршрута. В многошаговых алгоритмах узел источник задает полный маршрут следования пакета через промежуточные маршрутизаторы. Одношаговые алгоритмы делятся на: алгоритмы фиксированной маршрутизации. Все записи в таблице маршрутизации являются статическими. Администратор сети сам решает, на какие маршрутизаторы надо передавать пакеты с теми или иными адресами, например с помощью команды route занося записи в таблицу маршрутизации. Различают одномаршрутные таблицы, где всякий раз выбирается один и тот же маршрут для пакетов с одним адресом, в многомаршрутных могу т определяться несколько путей, обычно это резервные пути, фиксированная маршрутизация подходит для сетей с не очень сложной топологией, например в магистральных каналах. алгоритмы простой маршрутизации. В этом случае таблица маршрутизации вообще не строится, либо строится без участия 42 маршрутизаторов. Бывает несколько видов простой маршрутизации: Случайная маршрутизация — пакет отсылается в любом случайном направлении, исключая направление с которого он поступил. Лавинная маршрутизация — пакет широковещательно отсылается по всем направлениям кроме исходного. Маршрутизация на основе предыдущего опыта — выбор маршрута осуществляется по таблице, таблица строится как в алгоритме настройки отсылки кадров прозрачными мостами и коммутаторами — на основе адресов появляющихся на входных портах. алгоритмы адаптивной (или динамической) маршрутизации. Обеспечивают автоматическое обновление таблиц маршрутизации после изменения конфигурации сети. В таблицах маршрутизации для каждого маршрута обычно хранится время в течение которого данный маршрут может считаться действительным — время жизни маршрута. Адаптивные алгоритмы должны обеспечивать если не оптимальность то рациональность маршрута при достаточной скорости определения маршрутов и построения таблица, при этом система построения маршрутов является децентрализованной — распределённой. Адаптивные алгоритмы делятся на алгоритмы дистанционно векторного типа и алгоритмы состояния связей. В первом случае каждый маршрутизатор отсылает, маршрутизатор периодически широковещательно рассылает вектор, компонентами которого являются кратчайшие расстояния от данного маршрутизатора до всех известных ему сетей. Под расстоянием обычно понимается число промежуточных маршрутизаторов на пути - хопов, или время прохождения пакета от узла к узлу. Каждый маршрутизатор получая вектор с расстояниями от своего соседа наращивает полученные расстояния от сетей на расстояние до соседа, также получив данные от соседа наращивает полученный вектор о новых сетях и снова отправляет вектор, также сохраняет в своей таблице первый маршрутизатор в кратчайшем пути. Данные алгоритмы хорошо работают в небольших сетях, так как в сетях со сложной топологией и размером они засоряют трафик, также алгоритмы могут работать не всегда корректно. В случае появления нового маршрута в сети данная информация распространяется достаточно быстро, но если маршрут теряется, то данная информация распространяется очень медленно. Грубо говоря, это связано с механизмом рассылки таблиц, в которых хранится лишь информация о том, что у маршрутизатора есть путь до какого то маршрутизатора определенной длины (причем необязательно, что данный маршрутизатор соседний), в простейшем случае даже не посылается информация о, том через какой маршрутизатор лежит данный путь. Таким образом, даже если какой то маршрутизатор отключился, то маршрутизаторы, которые непосредственно не связаны с ним, продолжают посылать информацию о, том что у них есть путь, таким образом, непосредственно связанные маршрутизаторы могут начать считать, что путь лежит через уже через те маршрутизаторы. Наиболее распространённым протоколом использующий данный алгоритм является RIP IP, RIP IPX. Алгоритмы состояния связей. Обеспечивают информацией все маршрутизаторы для построения достаточно точного графа связей сети. Вершинами графа являются как маршрутизаторы, так и объединяемые ими сети, поиск маршрута может осуществляться на основе такого графа, например, по алгоритму Дейкстры. При загрузке маршрутизатора в сеть первым делом он узнает о своих соседях, рассылая специальный пакет HELLO, по всем двуточечным линиям, другие маршрутизаторы отвечают и посылают информацию о себе. При этом имена маршрутизаторов должны быть уникальны. Для оценки времени задержки на линии связи между соседями, маршрутизатор отправляет пакет ECHO и считает время через которое ответ вернется и делит его пополам, при этом для уточнения времени, echo может посылаться несколько раз. При этом можно 43 учитывать и не учитывать загрузку линии. Учет загрузки с одной стороны позволит, выбрать для отправки менее загруженную линию, но может привести при определении нового графа маршрута к перегрузке новой линии и так поочередно. Лучшим вариантом является отправка поочередно по параллельным маршрутам, либо с учетом пропускной способности каждой линии, например, по маршрутам где скорость доставки выше отправлять пакеты чаще. После того как маршрутизатор собрал информацию о своих соседях и время задержки до каждого соседа, он отправляет пакет в виде специальной таблицы. Такой пакет содержит имя маршрутизатора отправителя, порядковый номер пакета отправления, возраст пакета, и список соседей маршрутизаторов с временем задержки до каждого из них. Алгоритм отправки таких пакетов основан на алгоритме заливки. Если приходящий пакет новый, то он рассылается всем маршрутизаторам исключая направление откуда пакет пришел (или откуда пришел дубликат). Если приходит дубликат пакета, то дубликат удаляется. Каждый маршрутизатор отсылая новый пакет с таблицей увеличивает номер пакета на единицу, если пришедший пакет того же отправителя имеет номер меньший чем хранится у маршрутизатора получателя, то пакет с меньшим номером удаляется как устаревший. Также поле возраст пакета всякий раз уменьшается каждую секунду жизни пакета, если возраст становится меньше нуля, то пакет тоже удаляется, если новые пакеты приходят каждые 10 сек, то это вполне нормальная ситуация. Удаление пакетов с устаревшим возрастом необходимо для учета ситуаций с переполнением номера пакета и сброса номера в 0. Протоколами на основе алгоритмов состояния связей, являются протоколы is is стека osi и протокол OSPF стека TCP/IP. Мультикастингом (multicasting) называется рассылка дейтаграмм группе получателей. Для идентификации групп используются специальные адреса получателя; эти адреса в стеке протокола TCP/IP назначаются из класса D в диапазоне 224.0.0.0 – 239.255.255.255. Дейтаграмма, направленная на групповой адрес, должна быть доставлена всем участникам группы. Маршрутизация групповых дейтаграмм Веерная рассылка (Flooding) Веерная рассылка – наиболее простой метод маршрутизации групповых дейтаграмм, при котором дейтаграмма рассылается во все сети системы независимо от наличия в той или иной сети членов группы. При поступлении групповой дейтаграммы маршрутизатор проверяет, впервые ли он получает эту дейтаграмму. Если да, то маршрутизатор рассылает дейтаграмму через все свои интерфейсы, кроме того, с которого она была получена. Иначе дейтаграмма игнорируется. Отметим, что маршрутизатор должен хранить в памяти список всех "недавно" полученных групповых дейтаграмм от каждого источника для каждой группы и производить поиск в этом списке при получении каждой дейтаграммы. При интенсивном групповом трафике это потребует больших затрат памяти и мощности процессора. Другим существенным недостатком этого метода является то, что групповая дейтаграмма рассылается от источника всеми возможными путями: в некоторые сети дейтаграмма может быть передана несколько раз (разными маршрутизаторами). При этом наличие или отсутствие получателей не принимается в расчет. Плюсы веерной рассылки: простота реализации, надежность (за счет избыточности), независимость от маршрутных таблиц и протоколов маршрутизации. Остовые деревья (Spanning Trees) В системе сетей выбирается корневой маршрутизатор, после этого из графа системы выделяется подграф-дерево, соединяющий корневой маршрутизатор со всеми остальными маршрутизаторами системы. Эта процедура производится на этапе инициализации системы – в процессе работы дерево не изменяется. После построения остового дерева каждый маршрутизатор должен хранить для каждого из своих интерфейсов только флаг "этот интерфейс принадлежит/не принадлежит дереву". Групповая дейтаграмма от любого узла распространяется следующим образом: 44 полученная маршрутизатором дейтаграмма ретранслируется через все интерфейсы, принадлежащие остовому дереву, кроме того интерфейса, с которого она была получена. Метод остовых деревьев несколько лучше веерной рассылки – в том смысле, что теперь дейтаграммы распространяются по строго определенным маршрутам и в каждую сеть попадает только один экземпляр дейтаграммы. Также существенно уменьшена нагрузка на маршрутизаторы, которым больше не требуется хранить "исторические" таблицы дейтаграмм. Однако групповые дейтаграммы по-прежнему рассылаются во все сети независимо от наличия в них получателей, кроме того: требуется реализация механизма (протокола) выбора корневого узла и построения дерева; весь групповой трафик ложится на одни и те же связи (сети), составляющие, возможно, небольшое подмножество всей системы сетей; для некоторых пар отправитель-получатель путь по установленному дереву будет неоптимальным. RPF Метод RPF (Reverse Path Forwarding) состоит в следующем. Маршрутизатор получил через интерфейс I групповую дейтаграмму от источника S. Если через I лежит кратчайший маршрут от данного маршрутизатора до узла S, то ретранслировать дейтаграмму через все интерфейсы кроме того, с которого она получена. Иначе дейтаграмму игнорировать. В результате каждый маршрутизатор принимает для ретрансляции только те групповые дейтаграммы, которые следуют от источника к маршрутизатору по кратчайшему пути. Иными словами, дейтаграммы распространяются от источника ко всем маршрутизаторам системы по оптимальному остовому дереву с корнем в источнике. Для каждого источника такое дерево возникает автоматически по мере продвижения дейтаграммы. Однако поскольку ретрансляция групповой дейтаграммы производится маршрутизатором через все интерфейсы, кроме входного, некоторые экземпляры дейтаграммы являются лишними и засоряют сеть. Речь идет о тех дейтаграммах, которые будут отброшены соседними маршрутизаторами на основании того, что они прибыли с "неоптимальных" интерфейсов, то есть распространялись не по ветвям дерева. Избежать ретрансляции дейтаграммы через связи, не принадлежащие дереву, можно с помощью следующей модификации алгоритма: "Полученная групповая дейтаграмма предается только в те сети, где находятся маршрутизаторы, кратчайший маршрут к которым от узла S проходит через данный маршрутизатор." Следуя этому правилу, узел С не отправит дейтаграмму в В, поскольку кратчайший путь от источника до узла В проходит не через С. Важно отметить, что для реализации метода RPF необходимо иметь доступ к таблице маршрутов. Более того, для реализации модифицированного алгоритма требуется доступ к внутренним данным протокола внутренней маршрутизации (например, к базе данных состояния связей OSPF) – иначе нельзя сделать вывод о маршрутах, используемых другими узлами системы (источниками групповых дейтаграмм). Следующая модификация RPF призвана учесть наличие или отсутствие получателей групповой дейтаграммы в сетях системы с тем, чтобы дейтаграммы рассылались только в те сети, где есть члены данной группы. Применяемый для этого метод называется prunes – усечение (от английского prune – "обрезать ветви дерева"). Первая групповая дейтаграмма распространяется обычным образом по алгоритму RPF и достигает всех маршрутизаторов системы. Если к какому-то "конечному" маршрутизатору не присоединены члены данной группы (это устанавливается с помощью протокола IGMP), он посылает через тот интерфейс, откуда получил групповую дейтаграмму, специальное 45 сообщение Prune (по адресу данной группы). Это сообщение, принятое маршрутизатором, находящемся в вышестоящем узле дерева, означает "не посылать больше через этот интерфейс дейтаграммы от данного источника для данной группы". Вышестоящий маршрутизатор помечает этот интерфейс как pruned (усеченный) на определенный срок. По истечении этого срока процесс повторяется сначала. Однако имеется сообщение Graft (от английского "прививать растение"), позволяющее быстро подсоединиться к существующему дереву (то есть отменить ранее посланное Prune), не дожидаясь очередной рассылки "пробной" дейтаграммы. Если Prune получено от всех нижележащих маршрутизаторов, маршрутизатор отправляет Prune еще более вышестоящему маршрутизатору – таким образом можно усекать целые поддеревья. Метод RPF (с усечением) обладает следующими чрезвычайно существенными достоинствами: групповые дейтаграммы от каждого источника рассылаются по оптимальным путям – и эти пути определяются динамически в момент рассылки; при этом учитывается членство в группах – дейтаграммы в сети, где нет получателей, не рассылаются; групповой трафик распределяется по различными сегментам системы сетей, а не концентрируется в определенном подмножестве связей. Недостатки рассматриваемого метода: Каждый маршрутизатор должен хранить таблицу, в которой отслеживается получение сообщений Prune, и производить поиск в ней при получении каждой дейтаграммы. Размер этой таблицы равен произведению числа интерфейсов, числа групп и числа источников, дейтаграммы от которых проходили через маршрутизатор. (Отметим, что источники нужно запоминать тоже, так как для каждого источника создается свое дерево рассылки.) Безусловно, эта таблица не так велика, как при использовании веерной рассылки, но при интенсивном групповом трафике ее поддержка может отнять существенные ресурсы. Первая групповая дейтаграмма и, периодически, последующие "пробные" распространяются по всей системе сетей. При этом если в группе мало членов, а система велика (например, Интернет), возникает избыточный трафик, состоящий как из ретранслируемых экземпляров дейтаграммы, так и из потока Prune-сообщений, которые к тому же требуется обработать и внести в таблицу. Необходимость наличия интерфейса к структурам данных модуля маршрутизации (или необходимость создания "сопровождающего" протокола маршрутизации) увеличивает сложность реализации RPF. Несмотря на описанные недостатки, именно метод RPF лежит в основе многих протоколов групповой маршрутизации. CBT Метод CBT (Core Based Trees, Деревья с фиксированным ядром) основан на том, что для каждой группы назначается главный маршрутизатор, называемый ядром, – он будет корнем дерева рассылки. Все маршрутизаторы, к которым могут быть подключены потенциальные члены группы, знают адрес ядра. После того, как член группы зарегистрировался на маршрутизаторе с помощью протокола IGMP, маршрутизатор посылает в сторону ядра сообщение Join для присоединения к дереву рассылки. Промежуточные маршрутизаторы, пересылая это сообщение в сторону ядра, одновременно помечают интерфейсы, через которые получены сообщения Join, как принадлежащие дереву рассылки 46 для данной группы. Сообщение следует до ядра или до первого маршрутизатора, уже присоединенного к дереву рассылки. Cостояние принадлежности к дереву имеет определенный срок годности, поэтому периодически требуется посылка подтверждений. Отметим, что каждый маршрутизатор посылает подтверждение вышестоящему (следующему по пути к ядру) маршрутизатору. Неподтвержденные в течение некоторого времени ветви дерева усекаются. Рассылка же самих групповых дейтаграмм маршрутизаторами происходит аналогично методу остовых деревьев: дейтаграмма рассылается через все интерфейсы, принадлежащие дереву рассылки, кроме того, с которого дейтаграмма была получена. Если источник дейтаграммы не является членом группы, то его маршрутизатор сначала инкапсулирует групповую дейтаграмму в обычную, адресованную ядру, а ядро уже инициирует групповую рассылку по дереву. Достоинства этого метода: все групповые дейтаграммы рассылаются только участникам группы (в отличие от RPF нет "пробных" дейтаграмм); размер таблицы принадлежности интерфейсов к деревьям рассылки, которую требуется хранить на маршрутизаторе, меньше чем при использовании метода RPF (произведение числа групп на число интерфейсов; для всех источников одной группы используется одно дерево); не требуется доступ к маршрутным таблицам. Недостатки CBT аналогичны недостаткам метода остовых деревьев: весь групповой трафик ложится на одни и те же связи (сети), составляющие, возможно, небольшое подмножество всей системы сетей; узким местом является ядро; для некоторых пар отправитель-получатель путь по установленному дереву будет неоптимальным. 3.9 Лабораторная работа №8 Кэширующий HTTP прокси-сервер и SOCKS5 прокси-сервер Цель работы: написать консольные приложения- кэширующий HTTP прокси-сервер и SOCKS5 прокси-сервер; HTTP Кэширующий Прокси HTTP прокси реализуется в соответствии c HTTP протоколом и позволяет клиентам получать через себя доступ к веб серверам, таким образом, клиент по HTTP протоколу отправляет прокси- серверу те же HTTP запросы, какие бы он посылал на требуемый сервер. Задача прокси -сервера транслировать эти запросы на запрашиваемый сервер и осуществлять транспорт HTTP трафика через себя клиенту, при этом прокси сервер может изменять параметры HTTP запросов клиентов и ответа сервера и транслировать клиенту модифицированные объекты и заголовки ответа. Задача кэширующего прокси сервера сохранять проходящие через него страницы и объекты, и если клиенты запросили объект, который уже был сохранен на сервере, то сразу отправлять этот объект клиенту не скачивая его с веб сервера в случае если этот объект на веб сервере не менялся, при этом если объект на веб сервере обновился, информацию об этом необходимо получать с помощью заголовков if-modified-since, if-none-match. В языках программирования уже есть готовые компоненты для работы с HTTP сервером, которые позволяет переопределять HTTP обработчик запросов и получать доступ к передаваемым данным, полям запроса, анализировать их и делать новый запрос к серверу в 47 качестве HTTP клиента. Рекомендуемая литература: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE% D0%B2%D0%BA%D0%B8_HTTP http://msdn.microsoft.com/enus/library/system.net.httpwebrequest.ifmodifiedsince(v=vs.71).aspx http://msdn.microsoft.com/ru-ru/library/system.net.httpwebrequest(v=vs.90).aspx Пример, C#: Класс HttpWebRequest предоставляет поддержку свойств и методов, определенных в классе WebRequest, а также дополнительных свойств и методов, позволяющих пользователю взаимодействовать непосредственно с серверами, используя протокол HTTP. Свойство HttpWebRequest.IfModifiedSince хранит информацию из заголовка ifmodified-since. Пример использования: // Create a new 'Uri' object with the mentioned string. Uri myUri =new Uri("http://www.contoso.com"); // Create a new 'HttpWebRequest' object with the above 'Uri' object. HttpWebRequest myHttpWebRequest= (HttpWebRequest)WebRequest.Create(myUri); // Create a new 'DateTime' object. DateTime today= DateTime.Now; if (DateTime.Compare(today,myHttpWebRequest.IfModifiedSince)==0) { // Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable. HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse(); Console.WriteLine("Response headers \n{0}\n",myHttpWebResponse.Headers); Stream streamResponse=myHttpWebResponse.GetResponseStream(); StreamReader streamRead = new StreamReader( streamResponse ); Char[] readBuff = new Char[256]; int count = streamRead.Read( readBuff, 0, 256 ); Console.WriteLine("\nThe contents of Html Page are : \n"); while (count > 0) { String outputData = new String(readBuff, 0, count); Console.Write(outputData); count = streamRead.Read(readBuff, 0, 256); } // Close the Stream object. streamResponse.Close(); streamRead.Close(); // Release the HttpWebResponse Resource. myHttpWebResponse.Close(); Console.WriteLine("\nPress 'Enter' key to continue................."); Console.Read(); } else { Console.WriteLine("\nThe page has been modified since "+today); } Для создания прокси -сервера используйте библиотеку System.Net.Sockets. 48 SOCKS5 прокси-сервер Сокс сервер просто пробрасывает через себя TCP и UDP трафик. В данном приложении необходимо реализовать проброску tcp, используя протокол SOCKS5. С его помощью можно решать самые разные задачи: организовывать защищенный доступ к службам, расположенным за межсетевым экраном (firewall), скрывать свой истинный IP- адрес во время работы с недружелюбными сетевыми ресурсами или реализовать универсальный прокси-сервер, поддерживающий любые протоколы прикладного уровня (HTTP, FTP, POP3/SMTP, ICQ и т.д.). Основная задача данного протокола – внедрить в «нормальный» процесс обмена данными некоего посредника, называемого SOCKS-сервером или SOCKS-прокси. Когда клиент (поддерживающее SOCKS приложение: web-браузер Mozilla, клиент ICQ Miranda IM и др., см. ниже) желает отправить какую-либо информацию по сети, он устанавливает соединение не с реальным адресатом, а с SOCKS-сервером, который, в свою очередь, пересылает данные по назначению, но уже от своего имени. С точки зрения «настоящего» сервера (например, web-узла, который пользователь желает просмотреть в Mozilla Firefox) SOCKS-прокси является самым обыкновенным клиентом. Таким образом, сущность (IP-адрес) истинного клиента оказывается скрытой от обслуживающего его сервера. Это весьма удобное обстоятельство таит в себе потенциальную опасность (можете спрятаться вы, но ведь могут и от вас), поэтому реально существующие SOCKS-сервера имеют развитые схемы контроля доступа (запрет входящих и исходящих соединений по заданному перечню адресов) и поддерживают авторизацию пользователей по паролю (см. ниже). Отметим, что коль скоро SOCKS работает на более низком по сравнению с прикладным (а именно, транспортном) уровне модели OSI, его поддержка не потребует никаких изменений в логике работы клиента, а тем более – сервера. Действительно, все что нужно – это модифицировать реализацию функций, отвечающих за создание сетевого подключения и отправку данных: connect(), bind(), send() и т.п. На практике это обычно достигается перехватом системных вызовов с их последующей подменой поддерживающими SOCKS пользовательскими аналогами. Никаких правок в исходном коде клиентских приложений, а тем более самого доступа к исходным текстам, как правило, не требуется. Эта мощная процедура известна как «соксификация» и будет подробно рассмотрена ниже. Теперь, когда мы получили общее представление о SOCKS, можно перейти к болеедетальному рассмотрению данного протокола. Спецификация SOCKS5 Протокол SOCKS5 подробно описан в RFC1928. Как уже отмечалось ранее, SOCKS5 является протоколом транспортного уровня. Его «соседи» – TCP и UDP непосредственно используются для передачи данных, поступающих с прикладного уровня (от пользовательских приложений), а значит, SOCKS-прокси должен уметь корректно работать с каждым из них. Отметим также, что протокол ICMP, используемый утилитами ping и traceroute, находится ниже транспортного уровня, а потому соксификации, к сожалению, не поддается. Прежде чем отправлять какие-либо данные, клиент должен пройти процедуру авторизации на SOCKS-сервере. Для этого он открывает TCP-соединение с портом 1080 (значение по умолчанию) SOCKS-сервера и отправляет по нему сообщение, содержащее кодовые номера поддерживаемых им методов аутентификации. SOCKS-сервер выбирает один из методов по своему усмотрению и сообщает его номер клиенту. аутентификация может отсутствовать (на практике это скорее всего означает, что SOCKS-сервер различает клиентов по их IP-адресам) или производиться на основании имени пользователя и пароля. В последнем случае возможно большое количество различных вариантов, от тривиального «Username/Password Authentication» (RFC 1929) предусматривающего передачу пароля в открытом виде до куда более безопасного CHAP (зашифрованный пароль, открытые данные) и GSSAPI (RFC 1961), которое может использоваться для полной криптографической защиты 49 трафика. После успешной авторизации клиент получает возможность посылать запросы (команды), устанавливать исходящие соединения и даже принимать входящие. Установка исходящего TCP-соединения Для установки исходящего TCP-соединения, клиент отправляет SOCKS-серверу запрос «CONNECT», в котором указывает адрес и порт доставки. Для идентификации узлаполучателя могут использоваться как IP-адреса (поддерживаются IPv4/IPv6), так и полноценные доменные имена. В последнем случае SOCKS-сервер берет на себя заботу по их разрешению, так что сеть, в которой работает клиент, в принципе может обходиться и без DNS-сервера. В ответном сообщении SOCKS-сервер сообщает код ошибки (как обычно, 0 обозначает, что операция прошла успешно), а также IP-адрес (BND.ADDR) и TCP-порт (BND.PORT), которые будут использоваться для фактической связи с запрошенным узлом. Поскольку SOCKS-сервера, как правило, имеют более одного сетевого интерфейса, данный IP-адрес может отличаться от того, с которым было установлено управляющее соединение. После этого клиент открывает новый TCP-сеанс с BND.ADDR:BND.PORT и осуществляет отправку данных. Исходящее TCP-соединение разрывается одновременно с закрытием управляющей сессии. Заметим, что запрос «CONNECT» может быть отклонен SOCKS- прокси, если адреса источника (клиента) или получателя (сервера) запрещены. Установка исходящего UDP-соединения В отличие от потокового протокола TCP, подразумевающего установку сеанса, протокол UDP является датаграммным, а потому несколько более сложным в обращении. Его поддержка появилась лишь в SOCKS5. Перед отправкой UDP-датаграмм клиент запрашивает у SOCKS-сервера UDPассоциацию, используя для этого команду «UDP ASSOCIATE». UDP-ассоциация – это своего рода виртуальный сеанс между клиентом и SOCKS-сервером. В исходящем запросе клиент указывает предполагаемые адрес и порт, которые будут выступать в качестве источника будущих UDP-датаграмм. Если на момент установки UDP-ассоциации эта информация еще не известна, клиент должен использовать комбинацию 0.0.0.0:0 (или, скажем, x.x.x.x:0, если неизвестен только номер порта). В ответном сообщении SOCKS-сервер указывает IP-адрес (BND.ADDR) и UDP-порт (BND.PORT), на которые следует направлять исходящие датаграммы. При этом адрес и порт их реального получателя указываются прямо в теле (можно сказать, что имеет место UDP-инкапсуляция). Эти параметры, наряду с адресом и портом отправителя используются для принятия решения о допустимости отправки датаграммы. это создает дополнительную нагрузку на SOCKS-сервер: правила фильтрации необходимо применять к каждой UDP-датаграмме, тогда как в случае TCP-соединения его легитимность оценивается один раз, в момент исполнения SOCKS-сервером команды «CONNECT». Согласно требованиям стандарта, SOCKS-сервер должен следить за тем, чтобы IP-адрес отправителя датаграммы совпадал с адресом узла, создавшего UDP-ассоциацию. UDP-ассоциация разрушается одновременно с закрытием управляющего TCP-сеанса, в рамках которого была послана команда «UDP ASSOCIATE». Многие из существующих SOCKS-серверов испытывают серьезные проблемы, если между ними и клиентом, запросившим UDP-ассоциацию, располагается межсетевой экран с функцией NAT (Network Address Translation). Причина этого кроется в изменении адреса и порта отправителя, которое происходит в тот момент, когда UDP-датаграмма пересекает межсетевой экран. Как следствие, сервер и ничего не подозревающее клиентское приложение начинают говорить на разных языках: предполагаемый адрес и порт источника, указанные в команде «UDP ASSOCIATE» перестают соответствовать реальным параметрам получаемых SOCKS-сервером датаграмм. В результате они оказываются отброшенными как не принадлежащие UDP-ассоциации. Проблему можно было бы решить, указав в качестве предполагаемого источника 0.0.0.0:0 (см. выше), что должно интерпретироваться SOCKSсервером как «любая UDP-датаграмма, пришедшая с того же адреса, что и команда на создание ассоциации». К сожалению, большинство из реально существующих SOCKSсерверов трактуют стандарт более узко и не позволяют одновременно установить в ноль и 50 предполагаемый адрес, и порт отправителя. Из протестированных автором реализаций описанный здесь «фокус с пробросом UDP через NAT» позволяет проделать лишь одна – Dante. Прием входящих соединений Эта достаточно оригинальная возможность может оказаться полезной в случаях, когда клиент и «настоящий» сервер в описанной выше схеме меняются местами, что может произойти, например, в протоколах типа FTP. В целях дальнейшего рассмотрения будем предполагать, что между “клиентом” (стороной, собирающейся принять входящее соединение) и “сервером” (стороной, инициирующей входящее соединение) уже установлен “прямой” канал связи при помощи команды “CONNECT”. Для открытия “обратного” канала “клиент” должен послать SOCKS-серверу команду “BIND”, указав в ее параметрах IP-адрес и порт, которые будут использоваться им для приема входящего соединения. В ответ на это SOCKS- сервер сообщает IP-адрес и порт, выделенные им для поддержания “обратного” канала. Предполагается, что «клиент» передаст эти параметры «серверу» , используя средства, предоставляемые протоколами прикладного уровня (например, команду «PORT» протокола FTP). После того, как SOCKS-сервер примет (или отбросит) входящее соединение, он повторно уведомляет об этом «клиента», сообщая ему IP-адрес и порт, используемые “сервером”. Отметим, что прием входящих соединений может осуществлять лишь приложение, разработчики которого позаботились о поддержке SOCKS еще на этапе проектирования. В противном случае (если приложение работает с SOCKS-сервером через программу-соксификатор), оно не сможет предоставить корректную информацию об адресе ожидающего “обратной связи” сокета (т.е. сформирует неверную команду “PORT” в рассмотренном выше примере с FTP). «Цепочки» SOCKS Архитектура протокола SOCKS5 позволяет легко объединять SOCKS-сервера в каскады, или, как их еще называют «цепочки» («chains»). Примечательно, что все необходимые для этого действия могут быть произведены на стороне клиента. К «звеньям» цепочки предъявляется единственное требование: они должны «доверять» друг другу (т.е. допускать установку входящих и исходящих соединений). Если образующие каскад SOCKSсервера не являются анонимными (т.е. используют схемы аутентификации Username/Password, CHAP или подобные), необходимо также, чтобы пользователь мог успешно пройти процедуру авторизации на каждом из них. Предположим, что у нас имеется набор из N SOCKS-серверов с именами socks1, socks2, ...,socksN, удовлетворяющих всем вышеперечисленным требованиям. Тогда для создания каскада клиент может поступить следующим образом: В случае исходящего TCP-соединения: клиент подключается к socks1, проходит (при необходимости) процедуру авторизации и посылает команду «CONNECT», указав в качестве адреса доставки socks2. Выполняя этот запрос, socks1 создаст новое соединение с socks2 и будет исправно передавать всю идущую по нему информацию клиенту, при этом socks2 не будет даже догадываться, с кем он общается на самом деле. Далее процедура повторяется до тех пор, пока не будет установлено соединение между socks(N-1) и socksN. Последний сервер каскада подключается к непосредственно узлу, который интересует клиента. Передача данных происходит в обычном режиме: клиент отправляет пакет на сервер socks1, который, в свою очередь, передает его socks2, ... и так до тех пор, пока не будет достигнут конечный узел. В случае исходящего UDP-соединения: клиент подключается к socks1, проходит процедуру авторизации и последовательно посылает две команды: “CONNECT” (адрес доставки – socks2) и “UDP ASSOCIATE”. Таким образом, создаются два новых соединения: виртуальный UDP-канал между клиентом и socks1, а также TCP-сессия между socks1 и socks2. Используя эту TCP-сессию, клиент (от имени socks1) посылает команду “UDP ASSOCIATE” на сервер socks2 (открывает UDP-канал между socks1 и socks2) и “CONNECT” на сервер socks3. Процедура продолжается до тех пор, пока между всеми SOCKS-серверами каскада не будут установлены виртуальные UDPканалы. 51 Чтобы отослать какие-либо данные, клиент предварительно производит N-кратную инкапсуляцию UDP-датаграммы, указывая в качестве адреса доставки последовательно: socks1, socks2, socks3, socksN и адрес реального получателя, а затем отправляет ее на сервер socks1. Отметим, что на практике данный вариант каскадирования встречается крайне редко. Это связано с тем, что SOCKS-сервера, как и NAT Firewall'ы, могут изменить порт источника датаграммы, что приведет к проблемам, подробно описанным в разделе “Установка исходящего UDP-соединения”. Используя цепочки SOCKS-серверов, не требующих аутентификации, клиент может значительно повысить анонимность работы в Интернете (см. эпиграф). В Сети можно найти множество программ, реализующих описанные здесь схемы. Таковыми, например, являются SocksChain (http://www.ufasoft.com/socks/) для Windows или ProxyChains (http://proxychains.sourceforge.net) для Unix. Каскадирование SOCKS-серверов является также неотъемлемой частью некоторых соксификаторов, в первую очередь, FreeCap (http://www.freecap.ru/). SOCKS-сервера Теперь, когда принципы работы SOCKS-сервера нам хорошо знакомы, пора переходить от теории к практике. В мире существует большое количество программ, реализующих протокол SOCKS5. Они охватывают все популярные операционные системы (Unix, Windows, ...) и способы распространения (freeware, shareware, open-source и т.д.). Здесь мы вкратце рассмотрим наиболее известные (или интересные с точки зрения автора) реализации. Начнем, пожалуй, с SOCKS5 Reference Implementation (http://www.socks.permeo.com/), выполненной компанией NEC и принадлежащей в настоящий момент фирме Permeo. Текущая версия имеет номер 1.0r11 и датирована августом 2000 года. Как легко догадаться по названию, этот сервер является справочной реализацией протокола и, вообще говоря, не предназначен для промышленного использования. Однако, по не очень понятным мне причинам, он был включен в порты FreeBSD, а посему является де-факто стандартом на данной платформе. Продукт имеет поддержку GSSAPI и распространяется в исходных текстах, но по несвободной лицензии. Коммерческое применение данного сервера запрещено. Dante, разработанный норвежской компанией Inferno Nettverk, особенно популярен среди сторонников Linux. Продукт развивается, хотя и не очень бурно (последняя версия, 1.1.15, датирована 31 января 2005 года) и вполне пригоден для практического применения. Как уже упоминалось ранее, Dante позволяет корректно работать с UDP-ассоциациями даже в том случае, если они проходят через NAT Firewall. Программа распространяется в исходных текстах по лицензии BSD. В состав Dante входит библиотека для прозрачной соксификации Unix-приложений (см. ниже) Antinat (http://antinat.sourceforge.net/) - динамично развивающийся, но еще не завершенный открытый продукт, работающий на платформах Unix и Windows. Поддерживает интересные схемы аутентификации, например CHAP или HMAC-MD5. Умеет работать с цепочками SOCKS-серверов. В комплект поставки входит библиотека для разработки пользовательских приложений, поддерживающих SOCKS. Распространяется в исходных текстах. Лицензирован по GPL. Среди других разработок следует упомянуть отечественный 3proxy (http://security.nnov.ru/soft/3proxy/) , имеющий родную поддержку Unix и Win32, Delegate (http://www.delegate.org) и коммерческий SOCKS-сервер Hopster (http://www.hopster.com) для Microsoft Windows. Приведенный здесь список далеко не полон. Думается, что читателю не составит труда найти и другие сервера. Для этого можно воспользоваться поисковыми панелями репозитариев Freshmeat (http://www.freshmeat.net) или SourceForge (http://www.sf.net), а также поисковыми машинами общего назначения. Учитывая многообразие существующих SOCKS-серверов, мы не будем подробно останавливаться на процедуре их настройки. Вся необходимая для этого информация может 52 быть найдена в сопроводительной документации к конкретному программному продукту. Как правило, SOCKS-сервера имеют один или несколько конфигурационных файлов, позволяющих указать предпочтительные схемы авторизации и, что более важно, ограничить доступ к сервису по списку IP-адресов. Не пренебрегайте этой возможностью! Неправильно настроенный SOCKS-прокси может быть использован злоумышленниками для рассылки спама через корпоративный почтовый сервер (с точки зрения которого SOCKS-прокси – это один из установленных в фирме компьютеров, поэтому отправка почты с его IP-адреса, скорее всего, не будет запрещена) и выполнения других антиобщественных действий. SOCKS-клиенты Некоторые настольные приложения обладают встроенной поддержкой SOCKS. В их число входят web-браузеры, построенные на коде Mozilla и ряд клиентов сетей мгновенного обмена сообщениями (Miranda IM, Mirabilis ICQ). Для включения поддержки SOCKS в этих программах достаточно указать необходимые параметры в файле или диалоге настроек. Но что делать в случае, если приложение не умеет работать с SOCKS напрямую (классическим примером является Microsoft Internet Explorer)? Существует несколько вариантов решения данной проблемы. Если исходные тексты приложения доступны, можно собрать их заново, используя готовые клиентские библиотеки, например, входящие в состав Dante или Antinat. Однако, как уже упоминалось выше, наличие “исходников” не является обязательным требованием. Откомпилированное приложение можно заставить работать с SOCKS «обманным путем» при помощи программсоксификаторов, подменяющих стандартные функции для работы с сокетами их аналогами, поддерживающими SOCKS. Так, модифицированная функция connect(), устанавливающая соединение с заданным узлом на самом деле отсылает команду «CONNECT» на адрес указанного пользователем SOCKS-сервера, а «соксифицированная» функция sendto() выполняет инкапсуляцию UDP-датаграммы и отправляет ее, используя заранее установленную UDP-ассоциацию. Процедура подмены функций существенно зависит от типа операционной системы. Так, в мире Windows для этих целей применяются «вирусные» методики. Например, соксификатор может запускать указанный пользователем процесс в режиме «Suspend», после чего внедрять в его память код, загружающий специальную DLL-библиотеку, перехватывающую обращения к API-вызовам LoadLibrary/GetProcAddress, ответственным за подключение сторонних DLL и поиск в них экспортируемых функций. После этого соксификатор отслеживает момент загрузки wsock32.dll и подменяет запрашиваемые адреса функций Winsock указателями на их SOCKS-аналоги. В мире Unix, как это часто случается, все обстоит значительно проще. Динамический компоновщик ld.so использует специальную переменную окружения, LD_PRELOAD, а также файл /etc/ld.so.preload, чтобы определить список разделяемых библиотек, подлежащих предварительной загрузке до непосредственно запрашиваемых исполняемым файлом. Поскольку большая часть современных приложений использует динамическую компоновку, соксифицированные аналоги сетевых функций, оформленные в виде разделяемой библиотеки, перечисленной в LD_PRELOAD, будут найдены и использованы вместо стандартных вызовов, определенных в glibc. Этот метод, очевидно, не будет работать для приложений, использующих статическое связывание с glibc. Встречаться с таковыми (кроме низкоуровневых системных утилит) автору не приходилось. Кроме того, значение переменной LD_PRELOAD обрабатывается особым образом для исполняемых файлов, имеющих бит SUID. Среди клиентских (настольных) приложений они, как правило, не встречаются. Любая ли программа поддается соксификации описанными выше методами? Как легко видеть по ходу рассуждения, нет. Процедура внедрения кода Windows-соксификатора в чужой процесс может не сработать, если исполняемый файл имеет особую структуру, например, он сжат оригинальным образом или зашифрован. Кроме этого, пользовательские SOCKS-аналоги должны максимально точно повторять поведение (в том числе, эмулировать 53 недокументированные возможности) родных функций операционной системы, что, согласитесь, не всегда легко достижимо. Чтобы не быть голословными, приведем примеры конкретных программсоксификаторов. В среде Windows можно использовать SocksCap (http://www.socks.permeo.com/) от все той же фирмы Permeo (и с все той же неудобной лицензией, ограничивающей коммерческое применение) или открытый (распространяющийся по GPL) продукт FreeCap (http://www.freecap.ru), написанный нашим соотечественником Максимом Артемьевым. В последнем случае в вашем распоряжении окажутся также исходные тексты на языке Object Pascal (Delphi), с помощью которых вы сможете глубоко разобраться во всех обсуждаемых в статье вопросах, от процедуры внедрения в чужой процесс до точного формата SOCKS- сообщений. В Unix можно воспользоваться сценарием оболочки socksify, входящим в состав Dante. Наконец, рассмотрим особый случай - программы, обеспечивающие соксификацию всей системы целиком. В Windows этого можно достичь, подменив на диске файл wsock32.dll или более корректным образом, используя спецификацию Winsock Service Provider . В Unix достаточно добавить команду, устанавливающую значение переменной LD_PRELOAD в один из стартовых сценариев (например, rc.local) или внести изменения в файл /etc/ld.so.preload. Примером такого “общесистемного соксификатора” могут служить WideCap Максима Артемьева (пребывающий пока в состоянии бета-версии) или Permeo Security Driver. Вместо заключения Вот и подошло к концу наше повествование. Теперь, когда вы хорошо представляете себе, что такое SOCKS и с чем его едят, вам не составит труда придумать тысячу и одно применение данному протоколу. Например, на базе SOCKS-сервера можно организовать шлюз для доступа из локальной сети организации в Интернет. Это будет особенно удобно в случае, когда использование традиционного HTTP-прокси не может дать требуемых результатов (например, необходимо реализовать поддержку дополнительных протоколов, не связанных с web), а открывать полноценный доступ через NAT почему-либо представляется нецелесообразным. Предлагаемую схему можно инвертировать и возложить на SOCKSсервер функции “стража”, допускающего выделенных пользователей (скажем, находящихся в командировке сотрудников службы технической поддержки) к внутренним ресурсам компании (корпоративной базе данных). Можно... да мало ли чего можно придумать, имея необходимые знания и смекалку? Дерзайте! Таблица 1. Некоторые методы SOCKS-аутентификации Код Название метода 0x00 No Authentication Required (Аутентификация отсутствует) 0x01 GSSAPI (RFC 1961) 0x02 Username/Password (RFC 1929) 0x03 Challenge-Handshake Authentication Method (CHAP) 0x05 Challenge-Handshake Authentication Method (CRAM) Рекомендуемая литература: http://ru.wikipedia.org/wiki/SOCKS http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcplistener.aspx http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcpclient.aspx http://rfc2.ru/1928.rfc 54 Пример, C#: Для реализации приложения используйте классы: TcpListener- Прослушивает подключения от TCP-клиентов сети. TcpClient - Предоставляет клиентские подключения для сетевых служб протокола TCP. TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 1080); server.Start(); TcpClient client = server.AcceptTcpClient();//Ожидаем подключения от браузера Проверяем наш браузер на то, с каким протоколом он работает: byte SOCKS_VERSION = 5; byte SOCKS_NOAUTH = 0; byte SOCKS_REPLYSUCCESS = 0; byte SOCKS_IPV4ADDR = 1; byte SOCKS_DNSNAME = 3; NetworkStream socksClientStream = socksClient.GetStream(); /* ***************************************************** * supported methods part * ***************************************************** */ byte[] authFields = new byte[2]; socksClientStream.Read(authFields, 0, 2); Console.WriteLine(string.Format ("authFields: version {0} methods {1}", authFields[0], authFields[1])); // read n supported methods byte[] methods = new byte[authFields[1]]; socksClientStream.Read(methods, 0, methods.Length); Console.WriteLine("socks client supports " + methods.Length.ToString() + " methods"); Устанавливаем версию SOCKS и метод без аутентификации: /* ***************************************************** * method selection part * ***************************************************** */ // return version and auth method "no auth" byte[] selectedAuthMethod = { SOCKS_VERSION, SOCKS_NOAUTH }; socksClientStream.Write(selectedAuthMethod, 0, 2); Затем устанавливаем соединение с удаленным сервером, к которому был направлен запрос от браузера: /* ***************************************************** * server client connection part * ***************************************************** */ byte[] bintargetport = new byte[2]; socksClientStream.Read(bintargetport, 0, 2); 55 byte[] tmp_byteorder = new byte[2]; tmp_byteorder[0] = bintargetport[1]; tmp_byteorder[1] = bintargetport[0]; target_port = (int)BitConverter.ToUInt16(tmp_byteorder, 0); Console.WriteLine("requesting " + connection_target target_port.ToString()); + serverClient = new TcpClient(connection_target, target_port); /* ***************************************************** * reply part * ***************************************************** */ if (serverClient.Connected) { // reply successful audience byte[] reply = new byte[10]; //version reply[0] = SOCKS_VERSION; // replycode reply[1] = SOCKS_REPLYSUCCESS; //reserved and 0 reply[2] = 0; // addresstype reply[3] = 1; string ip = serverClient.Client.LocalEndPoint.ToString().Split(':')[0]; IPAddress ipaddr = IPAddress.Parse(ip); reply[4] = ipaddr.GetAddressBytes()[0]; reply[5] = ipaddr.GetAddressBytes()[1]; reply[6] = ipaddr.GetAddressBytes()[2]; reply[7] = ipaddr.GetAddressBytes()[3]; int port = int.Parse(serverClient.Client.LocalEndPoint.ToString().Split(':')[1]); // read unsigned integer in networkoctet order reply[8] = BitConverter.GetBytes((UInt16)port)[0]; reply[9] = BitConverter.GetBytes((UInt16)port)[1]; socksClientStream.Write(reply, 0, 10); Console.WriteLine("writing reply"); Etc.. } Ниже приведен простейшего HTTP прокси сервера на Python. from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer from SocketServer import ThreadingMixIn import urllib2, sys, re, httplib, urlparse class ProxyHandler( BaseHTTPRequestHandler ): server_version = '' sys_version = '' ":" + 56 def do_HEAD( self ): print "HEAD" def log_message(self,format,*args): return def do_POST( self ): print '-------------------------------' print "POST" requested_url = self.requestline.split()[1] parsed_url = urlparse.urlsplit( requested_url ) cutted_url = urlparse.urlunsplit( ( '', '', parsed_url.path, parsed_url.query, '' ) ) print parsed_url.hostname print parsed_url.path print parsed_url.query print requested_url port = 80 if None == parsed_url.port else parsed_url.port req_headers = {} for x in self.headers.items(): req_headers[x[0]] = x[1] print req_headers body = self.rfile.read(int(self.headers['content-length'])) print 'body -- ',body conn = httplib.HTTPConnection( parsed_url.hostname, port ) conn.request( 'POST', cutted_url, body,headers = req_headers ) response = conn.getresponse() print response.status self.send_response( response.status ) #resp_headers = [] #if 'content-type' in response.msg.dict: # resp_headers.append( ( 'content-type', response.msg.dict['contenttype'] ) ) #if 'date' in response.msg.dict: # resp_headers.append( ( 'date', response.msg.dict['date'] ) ) #if 'set-cookie' in response.msg.dict: # resp_headers.append( ( 'set-cookie', response.msg.dict['set-cookie'] ) ) #if 'location' in response.msg.dict: # resp_headers.append( ( 'location', response.msg.dict['location'] ) ) #for x in resp_headers: # self.send_header( x[0], x[1] ) #self.end_headers() for x in response.msg.items(): self.send_header( x[0], x[1] ) self.end_headers() html = response.read() self.wfile.write( html ) self.connection.close() conn.close() print 'End - post' return 57 def do_GET( self ): print '--------------------------------------' print 'GET' requested_url = self.requestline.split()[1] parsed_url = urlparse.urlsplit( requested_url ) cutted_url = urlparse.urlunsplit( ( '', '', parsed_url.path, parsed_url.query, '' ) ) port = 80 if None == parsed_url.port else parsed_url.port #if 'accept' in self.headers.dict: # req_headers['accept'] = self.headers.dict['accept'] #if 'accept-charset' in self.headers.dict: # req_headers['accept-charset'] = self.headers.dict['accept-charset'] #if 'accept-language' in self.headers.dict: # req_headers['accept-language'] = self.headers.dict['accept-language'] #req_headers['cache-control'] = 'no-cache' #req_headers['pragma'] = 'no-cache' #req_headers['user-agent'] = 'Mozilla/5.0' #if 'referer' in self.headers.dict: # req_headers['referer'] = self.headers.dict['referer'] #if 'host' in self.headers.dict: # req_headers['host'] = self.headers.dict['host'] #for x in self.headers.dict.keys(): # if len( x ) >= 6 and x[:6] == 'cookie': # req_headers[x] = self.headers.dict[x] #for x in self.headers.dict.keys(): # req_headers[x] = self.headers.headers[x] req_headers = {} for x in self.headers.items(): req_headers[x[0]] = x[1] print req_headers conn = httplib.HTTPConnection( parsed_url.hostname, port ) conn.request( 'GET', cutted_url ,'' ,req_headers ) response = conn.getresponse() #if response.status not in ( 200, 302, 301, 204 ): # print requested_url + ' - ' + str( response.status ) # print self.headers.headers # print response.msg.headers # self.send_response( response.status ) # self.end_headers() # self.connection.close() # conn.close() # return #resp_headers = [] #if 'content-type' in response.msg.dict: # resp_headers.append( ( 'content-type', response.msg.dict['contenttype'] ) ) #if 'date' in response.msg.dict: # resp_headers.append( ( 'date', response.msg.dict['date'] ) ) #if 'set-cookie' in response.msg.dict: 58 # resp_headers.append( ( 'set-cookie', response.msg.dict['set-cookie'] ) ) #if 'location' in response.msg.dict: # resp_headers.append( ( 'location', response.msg.dict['location'] ) ) self.name = '' self.send_response( response.status ) print response.status print parsed_url.hostname, ':', port print response.msg.items() i=0 for x in response.msg.items(): i=i+1 if(x[0]!='transfer-encoding'): print '--- ', x[0],' : ' ,x[1] if(x[0]!='connection'): self.send_header( x[0], x[1] ) else: self.send_header( 'connection', 'close' ) self.end_headers() #self.wfile.write( response.status ) #self.wfile.write( ' content-type: text/html' ) html = response.read() self.wfile.write( html ) #self.wfile.flush() #self.wfile.close() conn.close() self.connection.close() print 'END -- GET' return 0 class ThreadedHTTPServer( ThreadingMixIn, HTTPServer ): daemon_threads = True if __name__ == '__main__': proxy = ThreadedHTTPServer( ( 'localhost', 19277 ), ProxyHandler ) try: proxy.serve_forever() except KeyboardInterrupt: print 'End of server' proxy.server_close() 3.10 Лабораторная работа №9 распределенный UDP сервер/ UDP клиент Цель работы: написать приложения клиент, сервер, эмитирующие работу протокола 59 UDP, обеспечить надежность доставки, автоматическое обнаружение расчетчиков; User Datagram Protocol Транспортный протокол для передачи данных в сетях IP без установления соединения. Он является одним из самых простых протоколов транспортного уровня модели OSI. В отличие от TCP, UDP не подтверждает доставку данных, не заботится о корректном порядке доставки и не делает повторов. Поэтому аббревиатуру UDP иногда расшифровывают как Unreliable Datagram Protocol (протокол ненадёжных датаграмм). Зато отсутствие соединения, дополнительного трафика и возможность широковещательных рассылок делают его удобным для применений, где малы потери, в массовых рассылках локальной подсети, в медиапротоколах и т.п. Распределенный UDP сервер/ UDP клиент Задача написать приложение раздающее задание, которое посылало бы данные на несколько приложений расчетчиков, затем все расчетчики производили бы какие-либо преобразования над данными и отсылали их обратно. В случае, если приложение раздающее задание не получило обработанные данные обратно, оно должно отправить начальные данные другому расчетчику. Обеспечение надежности доставки Для обеспечения надежности доставки можно использовать следующие методы: хэшфункции, кода Хэмминга или Рида Соломона, контрольные суммы. На примере хэшфункции: Вычисляем хэш-функцию от данных, отправляем ее вместе с данными, получатель вычисляет свою хэш-функцию от полученных данных, сравнивает ее с полученной хэшфункцией, если все передалось успешно - они совпадут. Автоматическое обнаружение расчетчиков Например: Создаем сервер с заранее известным портом. И несколько клиентов, один из которых будет раздавать задания, а остальные производить расчеты. Все клиенты регистрируются на сервере, как «расчетчики» и один, как «раздающий задания». Затем сервер передает данные о расчетчиках раздающему задания, тот в свою очередь посылает данные для расчета напрямую расчетчикам. Данный вариант не является эталонным. Принимаются любые другие, лишь бы выполняли поставленную задачу. Рекомендуемая литература: http://helper10.narod.ru/i27.htm http://tools.ietf.org/html/rfc768 http://docs.oracle.com/javase/1.4.2/docs/api/java/net/DatagramSocket.html http://docs.oracle.com/javase/1.4.2/docs/api/java/net/DatagramPacket.html Пример Java: Для работы с датаграммными сокетами приложение должно создать сокет на базе класса DatagramSocket, а также подготовить объект класса DatagramPacket, в который будет записан принятый от партнера по сети блок данных. Канал, а также входные и выходные потоки создавать не нужно. Данные передаются и принимаются методами send и receive, определенными в классе DatagramSocket. В классе DatagramSocket определены два конструктора, прототипы которых представлены ниже: public DatagramSocket(int port); public DatagramSocket(); Первый из этих конструкторов позволяет определить порт для сокета, второй предполагает использование любого свободного порта. Обычно серверные приложения работают с использованием какого-то заранее определенного порта, номер которого известен клиентским приложениям. Поэтому для 60 серверных приложений больше подходит первый из приведенных выше конструкторов. Клиентские приложения, напротив, часто применяют любые свободные на локальном узле порты, поэтому для них годится конструктор без параметров. Прием и передача данных на датаграммном сокете выполняется с помощью методов receive и send, соответственно: public void receive(DatagramPacket p); public void send(DatagramPacket p); В качестве параметра этим методам передается ссылка на пакет данных (соответственно, принимаемый и передаваемый), определенный как объект класса DatagramPacket. Этот класс будет рассмотрен позже. Еще один метод в классе DatagramSocket, которым вы будете пользоваться, это метод close, предназначенный для закрытия сокета: public void close(); Перед тем как принимать или передавать данные с использованием методов receive и send вы должны подготовить объекты класса DatagramPacket. Метод receive запишет в такой объект принятые данные, а метод send - перешлет данные из объекта класса DatagramPacket узлу, адрес которого указан в пакете. Подготовка объекта класса DatagramPacket для приема пакетов выполняется с помощью следующего конструктора: public DatagramPacket(byte ibuf[], int ilength); Этому конструктору передается ссылка на массив ibuf, в который нужно будет записать данные, и размер этого массива ilength. Если вам нужно подготовить пакет для передачи, воспользуйтесь конструктором, который дополнительно позволяет задать адрес IP iaddr и номер порта iport узла назначения: public DatagramPacket(byte ibuf[], int ilength, InetAddress iaddr, int iport); Таким образом, информация о том, в какой узел и на какой порт необходимо доставить пакет данных, хранится не в сокете, а в пакете, то есть в объекте класса DatagramPacket. Помимо только что описанных конструкторов, в классе DatagramPacket определены четыре метода, позволяющие получить данные и информацию об адресе узла, из которого пришел пакет, или для которого предназначен пакет. Метод getData возвращает ссылку на массив данных пакета: public byte[] getData(); Размер пакета, данные из которого хранятся в этом массиве, легко определить с помощью метода getLength: public int getLength(); Методы getAddress и getPort позволяют определить адрес и номер порта узла, откуда пришел пакет, или узла, для которого предназначен пакет: public InetAddress getAddress(); public int getPort(); Если вы создаете клиент-серверную систему, в которой сервер имеет заранее известный адрес и номер порта, а клиенты - произвольные адреса и различные номера портов, то после получения пакета от клиента сервер может определить с помощью методов getAddress и getPort адрес клиента для установления с ним связи. 3.11 Лабораторная работа 10. Перехват сетевых пакетов Реализовать программу (сниффер) для перехвата пакетов в сети Wi-Fi. 61 Любым программам для мониторинга сети, инструментам безопасности необходим перехват сетевых пакетов. На языке C# и для Фреймворка Net существует по крайней мере две библиотеки: SharPcap и WinPKFilter. SharpPcap SharpPcapSharpPcap — библиотека для .NET, которая позволяет перехватывать пакеты. По сути, это обертка над библиотекой Pcap, которая используется во многих популярных продуктах. Например, сниффер Wireshark, IDS Snort. С SharpPCap также поставляется замечательная библиотека для парсинга пакетов — Packet.Net. Packet.Net поддерживает следующий протоколы: * Ethernet * LinuxSLL * Ip (IPv4 and IPv6) * Tcp * Udp * ARP * ICMPv4 и ICMPv6 * IGMPv2 * PPPoE * PTP * Link Layer Discovery Protocol (LLDP) * Wake-On-LAN (WOL) Работать с библиотекой достаточно просто: // метод для получения списка устройств CaptureDeviceList deviceList = CaptureDeviceList.Instance; // выбираем первое устройство в спсике (для примера) ICaptureDevice captureDevice = deviceList[0]; // регистрируем событие, которое срабатывает, когда пришел новый пакет captureDevice.OnPacketArrival += new PacketArrivalEventHandler(Program_OnPacketArrival); // открываем в режиме promiscuous, поддерживается также нормальный режим captureDevice.Open(DeviceMode.Promiscuous, 1000); // начинаем захват пакетов captureDevice.Capture(); Теперь в обработчике события device_OnPacketArrival мы можем работать с пакетом: static void Program_OnPacketArrival(object sender, CaptureEventArgs e) { // парсинг всего пакета 62 Packet packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); // получение только TCP пакета из всего фрейма var tcpPacket = TcpPacket.GetEncapsulated(packet); // получение только IP пакета из всего фрейма var ipPacket = IpPacket.GetEncapsulated(packet); if (tcpPacket != null && ipPacket != null) { DateTime time = e.Packet.Timeval.Date; int len = e.Packet.Data.Length; // IP адрес отправителя var srcIp = ipPacket.SourceAddress.ToString(); // IP адрес получателя var dstIp = ipPacket.DestinationAddress.ToString(); // порт отправителя var srcPort = tcpPacket.SourcePort.ToString(); // порт получателя var dstPort = tcpPacket.DestinationPort.ToString(); // данные пакета var data = tcpPacket.PayloadPacket; } } Так же библиотека позволяет создавать пакеты и отправлять, работать с дампами и многое другое. Без проблем работает на mono. У SharpPcap есть конкурент Pcap.net. По описанию возможности совпадают. WinPKFilter WinPKFilter — NDIS драйвер для перехвата пакетов. Поддерживаются различные операционные системы:x/ME/NT/2000/XP/2003/Vista/2008/Windows 7/2008R2. Плюсом драйвера является то, что он позволяет модифицировать и блокировать пакеты. Для некоммерческих проектов библиотека бесплатна. Для удобной работы с драйвером предоставляется библиотека. На сайте можно скачать обертки для этой библиотеки для следующих языков — C#, Delphi, VB, MS VC++, C++ Builder. Работать с WinPkFilter сложнее, чем SharpPcap, нужны хорошие знания в работе с неуправляемым кодов и в маршалинге. Да и размер кода получается намного больше. На официальном сайте можно задать вопрос на который Вы без проблем получите от автора (кстати русский). Перехватчик с использование библиотеки scapy на python. Далее описан сканер, который будет осуществлять пассивное сканирование сети методом перехвата SSID-идентификаторов. Весь проект занимает несколько строчек кода на Python, в основу положена библиотека Scapy (www.secdev.org/projects/scapy), предназначенная для манипуляции сетевыми пакетами. К сожалению, под Windows это реализуется на несколько порядков 63 сложнее, поэтому в качестве платформы мы выберем Linux. Установка scapy cd /scapy/ & python setup.py install. Далее можно приступить к написанию сканера. Сканер будет просматривать специальные фреймы, которые содержат уникальный идентификатор сети SSID (Service Set Identifier) и рассылаются точкой доступа. Их также называют Beacon-фреймами. По ним мы и будут определяться найденные сети. import sys from scapy import * print "Wi-Fi SSID passive sniffer" interface = sys.argv[1] #задаем название интерфейса в качестве дополнительного консольного аргумента def sniffBeacon(p): if p.haslayer(Dot11Beacon): print p.sprintf("%Dot11.addr2%[%Dot11Elt.info%|%Dot11Beacon.cap%]") sniff(iface=interface,prn=sniffBeacon) Вывод программы содержит информацию о перехваченных Beacon-фреймах: skvoz@box: sniffssid.py eth1 00:12:17:3c:b6:ed['netsquare4'|short-slot+ESS] 00:30:bd:ca:1e:1e['netsquare7'|ESS+privacy] Также можно поэкспериментировать с выбором haslayer (параметра мониторинга), поменяв его значение Dot11Beacon на: Dot11AssoResp, Dot11ProbeReq, Dot11ATIM, Dot11Auth, Dot11ProbeResp, Dot11Addr2MACField, Dot11Beacon, Dot11ReassoReq, Dot11Addr3MACField, Dot11Deauth, Dot11ReassoResp, Dot11Addr4MACField, Dot11Disas, Dot11WEP, Dot11AddrMACField, Dot11Elt, Dot11AssoReq, Dot11PacketList. В этом случае можно перехватить не только SSID точки доступа, но и всю остальную информацию о сети. К примеру, узнать информацию о физических идентификаторах пользователей и сетевых обращениях. Для этого мы задействуем протокол ARP: import sys, os from scapy import * interface = raw_input("enter interface") #пользователь задает интерфейс сети os.popen("iwconfig interface mode monitor") #перевод карты в режим монитора на заданном интерфейсе #функция перехвата MAC def sniffMAC(p): if p.haslayer(Dot11): mac = p.sprintf("[%Dot11.addr1%)|(%Dot11.addr2%)|(%Dot11.addr3%)]") 64 print mac #функция перехвата IP-адресов и показа ARP сообщений def sniffarpip(p): if p.haslayer(IP): ip = p.sprintf("IP - [%IP.src%)|(%IP.dst%)]") print ip elif p.haslayer(ARP): arp = p.sprintf("ARP - [%ARP.hwsrc%)|(%ARP.psrc%)]-[%ARP.hwdst%)|(%ARP.pdst%)]") print arp #уровни, которые мы мониторим sniff(iface=interface,prn=sniffMAC, prn=sniffarpip) Вывод skvoz@puffy: python sniff.py eth1 [ff:ff:ff:ff:ff:ff)|(00:30:bd:ca:1e:1e)|(00:30:bd:ca:1e:1e)] IP - [192.168.7.41)|(192.168.7.3)] ARP - [00:0f:a3:1f:b4:ff)|(192.168.7.3)]-[00:00:00:00:00:00)|(192.168.7.41)] 3.12 Лабораторная работа 11. SASL аутоинтефикация Реализовать аутоинтефикацию, используя основные механизмы простого протокола аутентификации. SASL (англ. Simple Authentication and Security Layer — простой уровень аутентификации и безопасности) — это фреймворк (каркас) для предоставления аутентификации и защиты данных в протоколах на основе соединений. Он разделяет механизмы аутентификации от прикладных протоколов, в теории позволяя любому механизму аутентификации, поддерживающему SASL, быть использованным в любых прикладных протоколах, которые используют SASL. Фреймворк также предоставляет слой защиты данных. Для использования SASL протокол включает команду для идентификации и аутентификации пользователя на сервере и для опциональной защиты переговоров последующей интерактивности протокола. Если это используется в переговорах, то слой безопасности вставляется между протоколом и соединением. В 1997 Джон Гардинер Майерс (John Gardiner Myers) написал изначальную спецификацию SASL (RFC 2222) при университете Карнеги-Меллона (Carnegie Mellon University). В 2006 году этот документ утратил силу после введения RFC 4422, под редакцией Алексея Мельникова (Alexey Melnikov) и Курта Зейлинга (Kurt Zeilenga). Механизмы SASL реализуют серию запросов и ответов. Определенные SASL механизмы включают: «EXTERNAL», используется, когда аутентификация отделена от передачи данных (например, когда протоколы уже используют IPsec или TLS); «ANONYMOUS», для аутентификации гостевого доступа (RFC 4505); «PLAIN», простой механизм передачи паролей открытым текстом. PLAIN является заменой устаревшему LOGIN ; «OTP», механизм одноразовых паролей. OTP заменяет устаревший механизм SKEY; «SKEY», система одноразовых паролей (устаревший); «CRAM-MD5»; «DIGEST-MD5»; «NTLM»; «GSSAPI»; GateKeeper (& GateKeeperPassport), разработана Microsoft для MSN Chat; «KERBEROS IV» (устаревший). Семья механизмов GS2 поддерживает произвольные GSSAPI механизмы в SASL. Это 65 сейчас стандартизовано в RFC 5801. ЛИТЕРАТУРА 1. Компьютерные сети: Принципы, технологии, протоколы: Учебное пособие для вузов/ В. Г. Олифер, Н. А. Олифер. - 3-е изд.. - СПб.: Питер, 2008. - 957[3] с.: ил.. 2. Компьютерные сети : Пер. с англ. / Э. Таненбаум ; пер. : В. Шрага. - 4-е изд. - СПб. : Питер, 2007. - 991[1] с. : ил. - (Классика Computer Science). - Библиогр.: с. 941-970. 3. Современные беспроводные сети: состояние и перспективы развития / И. А. Гепко [и др.] ; ред. В. Ф. Олейник. - Киев : ЕКМО, 2009. - 671 с. 4. Беспроводные сети Wi-Fi: учебное пособие / А. В. Пролетарский [и др.]. -М.: Интернет-Университет Информационных Технологий, 2007; М. : БИНОМ. Лаборатория знаний, 2007. - 215 с. 5. Сети. Беспроводные технологии: пер. с англ. / П. Беделл; пер. Р. М. Евтеев. - М.: НТ Пресс, 2008. -441 с. 6. Основы программирования на JAVA: Учебное пособие/ Р. В. Юдахин; - Томск: ТУСУР, 2004. - 195 с.: