МегаПредмет

ПОЗНАВАТЕЛЬНОЕ

Сила воли ведет к действию, а позитивные действия формируют позитивное отношение


Как определить диапазон голоса - ваш вокал


Игровые автоматы с быстрым выводом


Как цель узнает о ваших желаниях прежде, чем вы начнете действовать. Как компании прогнозируют привычки и манипулируют ими


Целительная привычка


Как самому избавиться от обидчивости


Противоречивые взгляды на качества, присущие мужчинам


Тренинг уверенности в себе


Вкуснейший "Салат из свеклы с чесноком"


Натюрморт и его изобразительные возможности


Применение, как принимать мумие? Мумие для волос, лица, при переломах, при кровотечении и т.д.


Как научиться брать на себя ответственность


Зачем нужны границы в отношениях с детьми?


Световозвращающие элементы на детской одежде


Как победить свой возраст? Восемь уникальных способов, которые помогут достичь долголетия


Как слышать голос Бога


Классификация ожирения по ИМТ (ВОЗ)


Глава 3. Завет мужчины с женщиной


Оси и плоскости тела человека


Оси и плоскости тела человека - Тело человека состоит из определенных топографических частей и участков, в которых расположены органы, мышцы, сосуды, нервы и т.д.


Отёска стен и прирубка косяков Отёска стен и прирубка косяков - Когда на доме не достаёт окон и дверей, красивое высокое крыльцо ещё только в воображении, приходится подниматься с улицы в дом по трапу.


Дифференциальные уравнения второго порядка (модель рынка с прогнозируемыми ценами) Дифференциальные уравнения второго порядка (модель рынка с прогнозируемыми ценами) - В простых моделях рынка спрос и предложение обычно полагают зависящими только от текущей цены на товар.

Включення прийому TCP-з'єднань





Після виконання зв'язування з адресою і перед тим, як який-небудь клієнт зможе підключитися до створеного сокету, сервер повинен включити прийом з'єднань за допомогою системного виклику listen ().

# Include <sys/socket.h>

int listen (int sockfd, int queue_ size);

· sockfd - дескриптор файлу сокета, створеним за допомогою виклику socket (),

· queue_size - число запитів на з'єднання з сервером, які можуть стояти в черзі.

Дана операція виконується тільки в програмі сервера.

Прийом запиту на встановлення TCP-з'єднання

Коли сервер отримує від клієнта запит на з'єднання, він створює новий сокет для роботи з новим з'єднанням. Перший же сокет використовується тільки для встановлення з'єднання. Додатковий сокет для роботи зі з'єднанням створюється за допомогою виклику accept(), що приймає чергове з'єднання.

# Include <sys/types.h>

# Include <sys/socket.h>

int accept (int sockfd, struct sockaddr * address, size_t * add_len);

· sockfd - дескриптор сокета, для якого ведеться прийом сполук;

· address - покажчик на узагальнену структуру адреси сокета з інформацією про клієнта; оскільки зв'язок використовує з'єднання адресу клієнта знати не обов'язково і допустимо задавати параметр address значенням NULL;

· add_len - розмір структури адреси, заданої параметром address, якщо значення address не дорівнює NULL.

Значення, що повертається, відповідає ідентифікатору нового сокета, який буде використовуватися для зв'язку. Доти, доки від клієнта не надійшов запит на з'єднання, процес, який видав системний виклик accept (), переводиться в стан очікування.

Дана операція виконується тільки в програмі сервера.

Підключення клієнта

Для виконання запиту на підключення до серверного процесу клієнт використовує системний виклик connect ().

# Include <sys/types.h>

# Include <sys/socket.h>

int connect (i nt csockfd, const struct sockaddr * address, size_t add_len);

· сsockfd - дескриптор файлу сокета клієнта, створеним за допомогою виклику socket ();

· address - покажчиком на узагальнену структуру адреси сокета, до якої перетвориться структура sockaddr_in, у разі передачі даних через мережу;

· size_t add_len - розмір зазначеної структури адреси сокета.

У разі успішного завершення виклику connect () він повертає значення 0. У випадку помилки, системний виклик connect () повертає значення -1, а змінна errno ідентифікує помилку.

Дана операція виконується тільки в програмі клієнта.

Пересилання даних

Для сокетів типу SOCK_STREAM дескриптори сокетів, отримані сервером за допомогою виклику accept () і клієнтом за допомогою виклику socked (), можуть використовуватися для читання або запису. Для цього можуть використовуватися звичайні виклики read () і write (), або спеціальні системні виклики send () і recv (), що дозволяють задавати додаткові параметри пересилання даних по мережі. Синхронізація даних при роботі з сокетом аналогічна передачу даних через програмний канал.

# Include <sys/types.h>

# Include <sys/socket.h>

ssize_t recv (int sockfd, void * buffer, size_t length, int flags);

ssize_t send (int sockfd, const void * buffer, size_t length, int flags);

· socfd - дескриптор сокета, через який читаються або записуються дані;

· buffer - буфер, в який вони поміщаються або звідки відсилаються через сокет;

· length - розмір буфера;

· flags - поле додаткових опцій при отриманні або передачі даних.

У разі успішного читання / запису системні виклики send () і recv () повертають число прочитаних / відісланих байт, або -1 у випадку помилки; в разі розірваної зв'язку (клієнт розірвав TCP-з'єднання) виклик recv () (або read ()) повертають нульове значення; якщо процес намагається записати дані через розірване TCP-з'єднання за допомогою write () або send (), то він отримує сигнал SIGPIPE, який можна обробити, якщо передбачена обробка даного сигналу.

У разі flags = 0 виклики send () і recv () повністю аналогічні системним викликам read () і write ().

Можливі комбінаціями констант параметра flags системного виклику send ():

· MSG_PEEK Процес може переглядати дані, що не "отримуючи" їх;

· MSG_OOB Звичайні дані пропускаються. Процес приймає тільки термінові дані, наприклад, сигнал переривання;

· MSG_WAIT ALL Повернення з виклику recv відбудеться тільки після отримання всіх даних.

Можливі комбінаціями констант параметра flags системного виклику recv ():

· MSG_OOB Передати термінові (out of band) дані;

· MSG_DONTROUTE При передачі повідомлення ігноруються умови маршрутизації протоколу нижчого рівня. Зазвичай це означає, що повідомлення надсилається за прямим, а не по найшвидшому маршрутом (найшвидший маршрут не обов'язково прямий і може залежати від поточного розподілу навантаження мережі).

Дані операції виконуються і в програмі сервера і в програмі клієнта.

Закриття TCP-з'єднання

Закриваються сокети так само, як і звичайні дескриптори файлового введення / виведення, - за допомогою системного виклику close(). Для сокета SOCK_STREAM ядро гарантує, що всі записані в сокет дані будуть передані приймаючому процесу.

Дані операції виконуються і в програмі сервера і в програмі клієнта.

Індивідуальне завдання:

1. Організувати взаємодію типу клієнт - сервер. Клієнт робить запит серверу на виконання якої-небудь команди. Сервер виконує цю команду і повертає результати клієнту.

2. Організувати взаємодію типу клієнт - сервер. Клієнт робить запит серверу про передачу файлів з певним розширенням з вказаної директорії. Сервер сканує вказану директорію і відправляє клієнтові список файлів, що задовольняють запиту.

3. Організувати взаємодію типу клієнт - сервер. Сервер при підключенні до нього нового клієнта висилає список IP-адрес вже підключених клієнтів. А іншим клієнтам розсилається повідомлення у вигляді IP-адреси про те, що підключився такий-то клієнт.

4. Організувати взаємодію типу клієнт - сервер. Клієнт при вході в зв'язок з сервером повинен ввести пароль. Дозволено зробити три спроби. Якщо пароль не вірний, сервер повинен блокувати IP-адресу клієнта на 5 хвилин.

5. Організувати взаємодію типу клієнт - сервер. Клієнти підключається до першого сервера, і передають запит на отримання певного файлу. Якщо цього файлу немає, сервер підключається до другого серверу і шукає файл там. Потім або знайдений файл пересилається клієнту, чи надсилають повідомлення, то такого файлу немає.

6. Організувати взаємодію типу клієнт - сервер. До сервера одночасно може підключитися тільки один клієнт. Інші клієнти заносяться в чергу, і їм висилається повідомлення про очікування звільнення сервера.

7. Організувати взаємодію типу клієнт - сервер. Клієнт відсилає рядок серверу. Сервер відсилає даний рядок на інші сервера, список яких зберігається у файлі, а там вже здійснюється пошук файлів містять цей рядок. Результати пошуку відсилаються клієнту.

8. Емуляція DNS сервера. Клієнт під'єднується до сервера, IP якого зберігається у файлі dns.url і робить йому запит на підключення до сервера "Ім'я сервера". DNS-сервер має список, що зберігається у файлі про відповідність імен серверів та IP-адрес. Якщо в списку немає "імені сервера" запитаного клієнтом, то сервер DNS підключається послідовно до інших серверів, що зберігається у файлі dns.url і т.д. Якщо сервер не знайдений, клієнту повертається відповідне повідомлення.

9. Організувати чат. До сервера підключаються клієнти. При підключенні клієнта сервер запитує ім'я, під яким клієнт буде відомий в з'єднанні. Сервер зберігає IP-адреси клієнтів, що підключаються і їх імена. Всі повідомлення кожного клієнта розсилаються іншим у вигляді "" ім'я клієнта "- повідомлення". Повідомлення розсилаються сервером всім клієнтам також при входженні у зв'язок нового клієнта, і виході якого клієнта

Хід роботи

1. Ознайомитися з теоретичними відомостями викладеними в конспекті лекцій, та теоретичних відомостях.

2. Отримати допуск до роботи.

3. Отримати індивідуальне завдання.

4. Написати програму що вирішує поставлене завдання.

5. Показати результат викладачеві.

6. Отримати тестові дані для перевірки програми.

7. Виконати перевірку програми з тестовими даними.

8. Скласти та захистити звіт.

Зміст звіту про роботу

1) титульна сторінка;

2) мета роботи;

3) короткі теоретичні відомості;

4) індивідуальне завдання;

5) опис роботи програми;

6) текст програми;

7) результати роботи програми;

8) висновки з виконаної роботи.


ЛАБОРАТОРНА РОБОТА № 2

(4 години)

Тема: Створення просто FTP- клієнта

Мета: Добути навички по створенню FTP - клієнтів

Короткі теоретичні відомості:

Детально розглянемо процес установки зв'язку з FTP-сервером. Щоб виконати яку-небудь команду, клієнтові потрібно встановити керівне з'єднання. Зробити це можна, підключившись на 21 порт (порт за замовчуванням у більшості FTP серверів) віддаленого комп'ютера. Як тільки з'єднання буде встановлено, FTP-сервер відправить вітання. Зазвичай в ньому міститься назва використовуваного сервера та інші інформаційні дані. Для продовження роботи клієнтові необхідно пройти авторизацію – відправити серверу свій логін і пароль. Логін передається командою USER [ім'я користувача], а пароль – командою PASS [пароль]. Якщо введені дані виявляться вірними, то сервер відправить повідомлення з кодом «230 OK». Текст цього повідомлення означає, що авторизація успішно пройдена і можна відправляти можливі команди. Наочний приклад установки керуючого з'єднання можна побачити на рисунку 1. На ньому зображено, як за допомогою telnet відбулось під’єднання до ftp-сервера.

Рисунок 1 – З’єднання за допомогою telnet

Після установки керуючого з’єднання можна посилати команди для отримання списку файлів або ж для копіювання самих файлів, але перед цим необхідно встановити друге з'єднання - для передачі даних. Насамперед, програмі-клієнтові необхідно відкрити будь-який вільний порт. Потім, віддаленому серверу необхідно послати дані у спеціальному форматі, які включатимуть: IP–адреса (тобто реальний твій IP) і порт (той який було відкрито для підключення). Всі ці дані відправляються за допомогою команди PORT. Допустимо, у ІР-адреса 192.168.0.1, а відкритим портом є 31337. В цьому випадку команда PORT виглядатиме таким чином: PORT 192,168,0,1,122,105. По специфікації RFC, номер порту потрібно передавати двома числами. У нашому прикладі це 122 і 105. Тепер ясно для чого ці цифри потрібні, але не ясно, яке відношення вони мають до порту 31337. Відповідь, як і повинно бути, чекає в RFC. На підставі цього документа, синтаксис команди PORT виглядає таким чином: PORT n1, n2, n3, n4, n5, n6, де n1-n4 - розділена комами IP -адреса, а n5*256+n6 - номер порту. Число 122 помножимо на 256, в результаті отримаємо 31232. Тепер до результату додайте 105. Після відправки команди PORT, сервер перевірить відправлені дані і якщо все гаразд, то буде створений канал для передачі даних (віддалений сервер встановить з'єднання з програмою), а значить, можна відправити команду LIST, і отримати список файлів заданої директорії. Після передачі даних сервер сам завершить друге з'єднання.


Рисунок 2 –Перший крок на шляху до FTP клієнта

У Delphi є готові компоненти, які істотно полегшують процес програмування FTP-клієнта, але на жаль, використовуючи їх, з'являються всякого роду обмеження. Краще написати свій FTP-клієнт повністю самому, для цього ми скористаємося мережевими функціями Windows. Навчившись ними користуватися, можна написати не тільки FTP-клієнт, але й будь-який інший мережевий додаток.

Перед викликом мережевих функцій потрібно ініціалізувати мережеву бібліотеку. Для цієї мети потрібно скористатися функцією Wsastartup, яка описана в модулі Winsock.pas таким чином:

0:Wsastartup (wversionrequested: word; var Wsadata:twsadata):Integeder; stdcall;

Функції потрібно передати два параметри:

1. wversionrequested - версія запрошуваної бібліотеки - 1.1 або 2.0. Для коректної вказівки потрібній версії краще всього скористатися функцією Makeword(). Їй потрібно передати два параметри - молодший і старший байт, тобто 1, 1.
2. Покажчик на структуру Wsadata. Після успішного виконання функції, в цю структуру потрапить інформація про бібліотеку, що ініціалізувала. У разі, коли функція виконалася успішно, вона поверне 0, інакше вона може повернути наступні коди помилок:

WSASYSNOTREADY - мережева підсистема не готова до мережевого з'єднання. WSAEFALUT - невірний покажчик на структуру Twsadata.

WSAPROCLIM - перевищена межа підтримуваних ОС завдань. WSAEINPROGRESS - в блокуючому режимі виконується операція, потрібно дочекатися її завершення. Отримати код помилки можна викликом функції Wsagetlasterror, про яку я розповім трохи пізніше, а зараз ми подивимося, як можна звільнити бібліотеку Winsock, що ініціалізувала. 0:function Wsacleanup:integer; stdcall;

Функції нічого не потрібно передавати як параметри, оскільки вона все, що вона робить – це звільняє бібліотеку, яку ініціалізувала. Вірогідно, її можна не викликати, оскільки в теорії, після завершення додатку ОС сама повинна це зробити, але краще звільнити бібліотеку самостійно:

0:function socket (af:integer; type:integer; protocol:integer):TSocket; stdcall;

Функція socket, після свого успішного виконання повертає об'єкт типу Tsocket, за допомогою якого ми і працюватимемо з мережею. Як параметри цієї функції необхідно передати:

1. AF - сімейство протоколів. Наш приклад використовуватиме тільки TCP, тому в цьому параметри указуватимемо Af_inet. Про решту можливих значень цього параметра можна дізнатися з модуля Winsock.pas або MSDN.

2. type - тип нового сокета. Може приймати значення Sock_stream (передача даних з установкою з'єднання) або Sock_dgram (всі дані передаються без установки з'єднання). Оскільки ми використовуватимемо протокол TCP, то в цьому параметрі ми указуватимемо Sock_stream.

3. protocol - протокол. Для TCP протоколу потрібно передати в цей параметр константу IPPROTO_TCP:

0:function bind (S:tsocket; var addr:tsockaddr; namelen:integer):integer; stdcall;

Для зв’язування локальної мережевої адреси з сокетом необхідно скористатися функцією bind. Ця функція стане в нагоді для організації каналу передачі даних. Її параметри:

1. s - створений за допомогою функції socket сокет.

2. addr - покажчик на структуру Tsockaddr.

3. Розмір структури Tsockaddr.

При успішному виконанні функція поверне 0, у разі помилки поверне Socket_error. Визначити код помилки можна за допомогою функції Wsagetlasterror(). Як другий параметр нам необхідно передавати покажчик на структуру Tsockaddr. При програмуванні мережевих застосувань це структура використовується повсюдно, тому ти винен її знати також добре, як і дірки в своїх зубах. Описується структура таким чином:

Структура Sockaddr_in:

0:Tsockaddrin = sockaddr_in; Sockaddr_in = record sin_family: u_short; sin_port: u_short; sin_addr:tinaddr; sin_zero: array[0..7] of Char; end;

У структурі присутні наступні параметри.

1. SIN_FAMILY - сімейство протоколів. Цей параметр аналогічний першому параметру функції socket. При використанні будь-яких Інтернет-протоколів тут потрібно вказати AF_INET.

2. SIN_PORT - порт, які використовуватиме наша програма для отримання даних. Якщо вказати в цьому параметрі 0, то система сама привласнить додатку вільний порт.

3. SIN_ADDR - структура Sockaddr_in, в якій зберігається інформація про IP адресі.

4. SIN_ZERO - поєднання по довжині структури sockaddr_in з sockaddr і навпаки. Для нашого прикладу даний параметр структури використовуватися не буде. 0:function listen (s:tsocket; backlog:integer):Integer; stdcall;

Після успішного виконання функції bind, можна приступати до прослушке порту в очікуванні гостей. Для це власне і створена функція listen. Функції потрібно передати всього два параметри:

1. S - сокет, який пов'язали з локальною адресою.

2. BACKLOG - максимальна кількість запитів на очікування підключення. Якщо функція виконається успішно, то вона поверне 0, в протівносм випадку помилки, коди яких можна дізнатися з модуля Winsock.pas. 0:function Accept (S:tsocket; addr: Psockaddr; Addrlen:pinteger):TSocket; stdcall;

Як тільки клієнт зробив спробу підключитися (у випадку, якщо ми виступаємо сервером), необхідно прийняти з'єднання. Цією нехитрою справою і займається функція Accept. Як параметри функції потрібно передати:

1. S - сокет.

2. ADDR - покажчик на структуру Sockaddr.

3. ADDRLEN - розмір структури Sockaddr. У разі успішного виконання, функція Accept повертає покажчик на сокет, через який ми можемо працювати з клієнтом, що підключився. 0:unction connect (s:tsocket; var name:tsockaddr; namelen:integer):integer; stdcall;

З параметрів функції Connect, яка виконує підключення, потрібно передати:

1. Сокет.

2. Структура sockaddr, в якій містяться дані для підключення до сервера (протокол, адреса, порт).

3. Розмір структури sockaddr. Як і більшість мережевих функцій, у разі успішного виконання дана функція поверне нам 0. 0:function send (s:tsocket; var Buf; len:integer; flags:integer):Integer; stdcall;

 

Для відправки даних в наборі Winsock є декілька функцій, серед яких є функція з ім'ям send. Розглянемо її параметри:

1. s - сокет, який використовуватиметься для відправки даних.

2. buf - буфер, в якому містяться дані для відправки.

3. len - розмір буфера.

4. flags - прапори, що впливають на метод відправки. Для нашого прикладу можна просто вказати 0. Якщо функція виконається успішно, тобто зможе відправити дані, то як результат вона поверне кількість фактично відправлених даних, інакше поверне помилку.

0:function recv (s:tsocket; var buf; len:integer; flags:integer):Integer; stdcall;

Функція виконує протилежну роль функції send - вона приймає дані. Її параметри повністю ідентичні параметрам функції send.

0:function Closesocket (s:tsocket):integer; stdcall;

Ця функція необхідна для закриття сокета. По правилах хорошого тону її прийнято викликати після функції shutdown, тим не менше, програмісти нехтують цим правилом і викликають її відразу, забуваючи про shutdown.

0:function Wsagetlasterror:integer; stdcall;

За допомогою цієї корисної функції можна отримати код виниклої помилки при виклику який-небудь іншій функції. Викликавши Wsagetlasterror(), вона відразу ж поверне код останньої виниклої в системі помилки. Надалі його можна проаналізувати і довести до користувача.

FTP-клієнт своїми руками

Ну ось, і настав той момент, коли нам потрібно закріпити всі теоретичні знання практикою. Запускаємо Delphi і створюємо новий проект типу Application. На формі розміщуємо один компонент Trichedit і один Tmainmenu. У Tmainmenu створені елементи меню:

1. З'єднання
- Підключитися
- Відключитися
- Настройки
2. Команди
- LIST
- CWD

По натисненню на кнопку «Настройки» викликатиметься додаткова форма, в якій потрібно буде ввести: ім'я користувача, пароль, сервер, порт. Її вигляд можна подивитися на рисунку 3.

Рисунок 3 – Форма з’єднання

Простенький дизайн FTP-клієнта готовий; тепер можна починати готувати начинку – писати код. Насамперед потрібно підключити до проекту модуль Winsock.pas, інакше виклик мережевих функцій буде неможливий. Тепер необхідно оголосити всі необхідні змінні. У розділі private оголоси наступні змінні: _wsadata:twsadata; _clientsocket:tsocket; _serversocket:tsocket; _clientaddr:sockaddr_in; _serveraddr:sockaddr_in; _mode:integer; _tempsocket:tsocket;

Ініціалізація мережевої бібліотеки виконується під час створення форми, а її звільнення – під час закриття вікна. Після ініціалізації мережевої бібліотеки можна спробувати з'єднатися з віддаленим сервером. По натисненню кнопки «З'єднатися» викликається процедура _connect(), якою потрібно передати всі необхідні для підключення дані (адреса сервера, логін, пароль, порт). Код цієї процедури можна побачити в лістингу 2.

Лістинг 2

procedure Tform1._Connect(ftp_server, ftp_port, user_name, user_pass: string);

begin

_clientsocket:=socket(Af_inet, Sock_stream, Ipproto_ip);

if _clientsocket=invalid_socket then begin

Geterror('Socket');

Exit;

end;

_clientaddr.sin_family:=AF_INET; _clientaddr.sin_addr.S_addr:=htonl(Inaddr_any); _clientaddr.sin_addr.S_addr:=inet_addr(pchar(ftp_server)); _clientaddr.sin_port:=htons(Strtoint(ftp_port));

Wsaasyncselect(_clientsocket, handle, Wm_mysockmess, Fd_read); Connect(_clientsocket, _clientaddr, sizeof(_clientaddr));

Sleep(100);

_send(_clientsocket, 'USER '+user_name);

_send(_clientsocket, 'PASS '+user_pass);

_send(_clientsocket, 'FEAT');

Весь код установки з'єднання з відділеним сервером відображений в лістингу 2, тому розглянемо його вміст докладно. На самому початку створюється новий сокет. Для того, щоб створити новий сонет, потрібно скористатися функцією SOCKET, яка після виконання поверне покажчик на створений сокет. Після виклику функції SOCKET, перевіряємо, чи не виникла помилка. Якщо так, то викликаю процедуру Geterror, передавши їй назву функції, що викликається. Процедура Geterror спробує отримати код помилки і врешті-решт проінформує користувача, надрукувавши в Trichedit відповідний текст. Якщо помилки не виникло, то можна починати готуватися до з'єднання з віддаленим сервером. Потрібно пам’ятати, щоб встановити з'єднання з сервером потрібно викликати функцію connect, якою потрібно передати структуру типу sockaddr_in. Щоб її передати, її потрібно заповнити. Після заповнення структури викликається функція Wsaasyncselect(). Дана функція встановлює асинхронний режим для вибраного сокета і примушує Windows генерувати повідомлення для мережевих подій. Таким чином, досить вказати повідомлення, яке повинне приходити вікну застосування при виникненні події на певному сокеті. Поглянемо на параметри, які потрібно передати функції.

1. s - сокет, за подіями якими необхідно спостерігати.

2. hwindow - вікно, яке прийматиме повідомлення.

3. wmsg - системна подія, яку потрібно генерувати.

4. levent - мережеві події, за якими ми спостерігатимемо. Як події можна вказати: Fd_read (виникає, коли прийшли дані), Fd_write (виникає, коли можна передавати дані), Fd_oob (виникає, коли прибули термінові дані), Fd_accept (виникає, коли в черзі сокета є нове підключення), Fd_connect (виникає при з'єднанні з сервером). Як третій параметр використовується Fd_read. В мить, коли на сокет прийдуть дані, головне вікно додатку отримає повідомлення Wm_mysockmess. Потрібно написати процедуру, яка перехоплюватиме потрібне повідомлення. Що собою являє Wm_mysockmess? У нашому прикладі це константа, яка оголошена і рівна Wm_user+1. Що таке Wm_user? Це число. Всі числа менше нього можуть вже використовуватися системою, щоб не було конфліктів. Відразу після Wsaasyncselect() викликається функція Connect, яка починає встановлювати з'єднання з віддаленим сервером. Після виконання функції Connect відразу починають відправлятися дані для проходження авторизації. Відправка даних реалізована в функції _send(). Як параметри їй потрібно передати сокет, через який будуть відправлені дані, і самі дані. Тепер повернемося до цікавої функції Wsaasyncselect(). Для перехоплення потрібної події потрібно оголосити спеціальну процедуру. У прикладі вона оголошена в розділі private таким чином: procedure NETMSG (var M:tmessage); message Wm_mysockmess;

Код тіла процедури можна побачити в лістингу 3. Як видно з опису, в процедуру передається структура типу Tmessage. У цій структурі є декілька параметрів, але нас цікавитимуть тільки два: Wparam і Lparam. У першому зберігається дескриптор сонета, на якому відбулася подія, а в другому тип події. Для перевірки типу події використовується керуюча структура CASE.

ЛІСТИНГ № 3

0:procedure Tform1.NetMSG(var M: Tmessage);

begin

case m.LParam of Fd_accept:

begin _tempsocket:=accept(m.WParam, nil, nil);

Wsaasyncselect(_tempsocket, handle, Wm_mysockmess, Fd_read+fd_close);

end;

Fd_read: _recv(m.WParam);

Fd_close: Closesocket(M.WParam);

end;

end;

При виникненні події Fd_read викликається процедура _recv, яка і виконує читання даних з певного сокета.

Завдання: Створити простий додаток для роботи по протоколу FTP. Додаток повинен забезпечувати з'єднання з сервером, передачу імені користувача і пароля, відображення списку каталогів і файлів, навігацію по каталогах, копіювання файлу або каталогу на сторону клієнта.

У додатку клієнта повинні бути текстові поля для введення імені сервера, користувача, пароля, об'єкт для відображення вмісту каталогів, кнопка для копіювання і видалення каталогів і файлів.

Реалізувати технологію drag & drop та можливість передачі команд сереверу.

Реалізувати завдання згідно варіанту.

Індивідуальне завдання:

  1. Реалізувати збереження імені користувача та паролю. Зробити можливість вибору користувача зі списку і шифрування паролів.
  2. Реалізувати фоновий режим завантаження.
  3. Вікно вибору фтп серверів зі списку.
  4. Реалізвати планувальник завдань.
  5. Розробити вікно черги завантажень.
  6. Реалізвати можливість запуски завантажених програм, архівів і документів.
  7. Реалізувати автоматичне перейменування файлів при співпаданні імен.
  8. Реалізувати можливість передачі файлів в пасивному режимі.

Хід роботи

  1. Ознайомитись із теоретичними відомостями викладеними в конспекті лекцій та теоретичних відомостях.
  2. Отримати допуск до роботи.
  3. Отримати індивідуальне завдання.
  4. Написати програму що вирішує поставлене завдання.
  5. Показати результат викладачеві.
  6. Отримати тестові дані для перевірки програми.
  7. Виконати перевірку програми з тестовими даними.
  8. Скласти та захистити звіт.

Зміст звіту про роботу

1) титульна сторінка;

2) мета роботи;

3) короткі теоретичні відомості;

4) індивідуальне завдання;

5) опис роботи програми;

6) текст програми;

7) результати роботи програми;

8) висновки з виконаної роботи.


ЛАБОРАТОРНА РОБОТА №3

(4 години)

Тема: створення простого WebBrowser-а.

Мета: засвоїти навички створення WebBrowser-а

Короткі теоретичні відомості:

У Delphi існує спеціалізований компонент, призначений для роботи із веб-сторінками – TWebBrowser. Розглянемо деякі властивості і функції TWebBrowser.

Процедури:

procedure GoBack;

procedure GoForward;

procedure GoHome;

procedure GoSearch;

procedure Refresh;

procedure Stop;

procedure Quit;

Назви цих процедур говорять самі за себе, а дозволяють вони здійснити управління переглядом – перейти з історії перегляду вперед, назад, перейти на сторінку, встановлену як домашня, відкрити сторінку пошуку, оновити поточну сторінку, зупинити завантаження сторінки, вийти.

Остання команда завершує роботу IE і очищає вікно.

Далі йде ціла група процедур:

procedure Navigate (const URL: WideString); ove rload;

procedure Navigate (const URL: WideString; var Flags: OleVariant); overload;

procedure Navigate (const URL: WideString; var Flags: OleVariant; var

TargetFrameName: OleVariant); overload;

procedure Navigate (const URL: WideString; var Flags: OleVariant;

var TargetFrameName: OleVariant; var PostData: OleVariant); overload;

procedure Navigate (const URL: WideString; var Flags: OleVariant;

var TargetFrameName: OleVariant; var PostData: OleVar iant;

var Headers: OleVariant); overload;

Всі вони призначені для зазначення того, як і яка сторінка повинна відображатися в браузері. У найпростішому випадку можна використовувати першу процедуру

procedure Navigate (const URL: WideStrin g);

Наприклад так:

WebBrowser1.Navigate ('http://www.delphikingdom.com/');

Або

WebBrowser1.Navigate ('http://www.delphikingdom.com/', empty, empty, empty, empty)

Для значення Flags визначені такі константи:

1 - Відкриває URL в новому вікні браузера

navNoHistory - Чи не заносить адресу в список History.

navNoReadFromCache - Чи не використовує збережену в кеші сторінку, а завантажує з сервера.

navNoWriteToCache - Чи не записує сторінку в дисковий кеш.

navAllowAutosearch - Якщо броузер не може знайти вказаний домен, він передає його в пошуковий механізм.

Все це можна також вручну встановити в налаштуваннях браузера.

TargetFrameName вказує ім'я фрейму, куди треба завантажити сторінку. Якщо присвоїти NULL сторінка просто завантажитися в поточне вікно.

PostData - вказує на дані, які потрібно відіслати, використовуючи метод HTTP POST. Якщо встановити в NULL, процедура Navigate буде використовувати метод HTTP GET.

Наступна досить цікава і корисна процедура

procedure ExecWB (cmdID: OLE CMDID; cmdexecopt: OLECMDEXECOPT); overload;

дозволяє здійснити управління браузером і викликати різні додаткові функції - друк, збереження та ін Використовує IoleCommandTarget інтерфейс для управління браузером.

CmdID - задає команду, яку потрібно виконати. Може приймати наступні значення:

OLECMDID_OPEN,

OLECMDID_NEW,

OLECMDID_SAVE,

OLECMDID_SAVEAS,

OLECMDID_SAVECOPYAS,

OLECMDID_PRINT,

OLECMDID_PRINTPREVIEW,

OLECMDID_PAGESETUP,

OLECMDID_SPELL,

OLECMDID_PROPERTIES,

OLECMDID_CU T,

OLECMDID_COPY,

OLECMDID_PASTE,

OLECMDID_PASTESPECIAL,

OLECMDID_UNDO,

OLECMDID_REDO,

OLECMDID_SELECTALL,

OLECMDID_CLEARSELECTION,

OLECMDID_ZOOM,

OLECMDID_GETZOOMRANGE,

OLECMDID_UPDATECOMMANDS,

OLECMDID_REFRESH,

OLECMDID_STOP,

OLECMDID_HIDETOOLBARS,

OLECMDID_SETPROGRESSMAX,

OLECMDID_SETPROGRESSPOS,

OLECMDID_SETPROGRESSTEXT,

OLECMDID_SETTITLE,

OLECMDID_SETDOWNLOADSTATE,

OLECMDID_STOPDOWNLOAD,

OLECMDID_FIND,

OLECMDID_ONTOOLBARACTIVATED,

OLECMDID_DELETE,

OLECMDID_HTTPEQUIV,

OLECMDID_E NABLE_INTERACTION,

OLECMDID_HTTPEQUIV_DONE,

OLECMDID_ONUNLOAD,

OLECMDID_PROPERTYBAG2,

OLECMDID_PREREFRESH

Якщо придивитися, то можна побачити, що деякі з них дублюються процедурами Stop, Refresh та ін.

Cmdexecopt - вказує додатково, як команда повинна виконуватися. Може приймати значення: OLECMDEXECOPT_DODEFAULT - Команда виповнюється так, як прийнято за замовчуванням.

OLECMDEXECOPT_PROMPTUSER - Перед виконанням виводитися вікно діалогу або додаткових налаштувань.

OLECMDEXECOPT_DONTPROMPTUSER - Чи не задається ніяких питань.

OLECMDEXECOPT_SHOWHELP - Виводиться довідка за запрошенням дії, але сама команда не виконується. Зручно для виклику з вашої програми довідки за IE.

Викликати цю команду бажано, і навіть потрібно, в блоці

try

WebBrowser1.ExecWB (OLECMDID_PRINT, OLECMDEXECOPT_PROMPTUSER);

except

end;

Ця команда викликає діалогове вікно друку документа. Якщо ж опустити конструкцію try ... except, то при натисканні "Скасувати" в цьому вікні буде згенеровано повідомлення про помилку типу:

raised exception class EOleException with message "Неможливо встановити властивість coISpan. Неприпустиме значення властивості. Потрібно ввести значення від 1 до 1000 ".

Тепер поговоримо про властивості

PopupMenu;

Як віконний елемент керування, TWebBrowser підтримує спливаючі меню, але воно буде з'являтися тільки, поки в браузер не завантажена сторінка. Далі - тільки меню IE. Можливий такий варіант для заборони появи стандартного меню:

...

private

{Private declarations}

procedure WMMouseActivate (var Msg: TMessage); message WM_MOUSEACTIVATE;

public

{Public declarations}

end;

...

...

procedure TForm1.WMMouseActivate (var Msg: TMessage);

begin

try

inherited;

/ / Права кнопка мишки?

if Msg.LParamHi = 516 then

Msg.Result: = MA_NOACTIVATEANDEAT;

/ / Тут можна вставити код для свідчення свого меню

except

end;

end;

property OffLine: WordBool;

Якщо привласнити True, то дозволяє завантажувати документи з локального кешу.

property LocationURL: WideString;

Позначено як "тільки для читання" і містить URL ресурсу, завантаженого в браузер.

Серед найважливіших / потрібних подій є:

OnDownloadBegin

OnDownloadComplete

OnBeforeNavigate2

OnNewWindow2

OnNavigateComplete2

OnDocumentComplete

OnDownloadBegin - відбувається, коли, вказавши URL, потрібно перейти по ньому. Тут можна задати, наприклад, анімацію або ProgressBar для індикації процесу завантаження сторінки (спільно з OnProgressChange).

OnDownloadComplete, OnDownloadComplete, OnNavigateComplete2 - відбувається, коли сторінка закінчила вантажитися.

Правда, тут є багато нюансів при завантаженні сторінок з графікою і фреймами – для кожного завантаження елемента будуть генеруватися нові події початку / закінчення завантаження, а крім того, якщо відключити завантаження малюнків / анімації / відео, так взагалі деякі з них не будуть відбуватися! Так що користуватися ними треба обережно.

OnBeforeNavigate2 - відбувається, коли ви переходите по клацанню на гіперпосиланні з основної сторінки, завантаженої в браузер. Сюди можна писати код, який наприклад, аналізує, куди користувач переходить, і відповідно, щось робити. Або заборонити відкривання нових вікно, або відкривати свої вікна (типу зробити TtabbedNotebook з IE на кожній сторінці)

OnNewWindow2 - відбувається, коли відкривається нове вікно браузера.

Завдання:

  1. Створити простий WebBrowser.
  2. Реалізувати навігацію між сторінками.
  3. Створити меню «Обране».
  4. Релізувати диспетчер завантажень.
  5. Реалізвати менеджер історії відвіданих вкладок.
  6. Реалізвати можливість відключення/включення малюнків.
  7. Релізувати можливість автоматичного збереження логіну та паролю на відвіданих сторінках.
  8. Реалізувати пошук на сторінці, на зразок популярних Web-браузерів.

Хід роботи

  1. Ознайомитись з теоретичними відомостями викладеними в конспекті лекцій, та теоретичних відомостях.
  2. Отримати допуск до роботи.
  3. Отримати індивідуальне завдання.
  4. Написати програму що вирішує поставлене завдання.
  5. Показати результат викладачеві.
  6. Отримати тестові дані для перевірки програми.
  7. Виконати перевірку програми з тестовими даними.
  8. Скласти та захистити звіт.

Зміст звіту про роботу

1) титульна сторінка;

2) мета роботи;

3) короткі теоретичні відомості;

4) індивідуальне завдання;

5) опис роботи програми;

6) текст програми;

7) результати роботи програми;

8) висновки з виконаної роботи.


ЛАБОРАТОРНА РОБОТА №4

(4 години)

Тема: Створення простого поштового клієнта

Мета: Здобути навички створення просто mail-клієнта.

Короткі теоретичні відомості:

Для роботи з мережею, в Delphi використовуються Indy компоненти, які можна знайти на декількох вкладках середовища розробки. Знайдіть на вкладці Indy Clients – компонент Idpop3, на вкладці Indy Misc - компонент Idmessage. За допомогою компоненту Idpop3 можна здійснити підключення до поштового сервера по протоколу Pop3 і отримати необхідну кількість повідомлень. Компонент IDMessage використовуватиметься, як буфер для одержуваного листа. Ще буде потрібно Memo для відображення тексту листа, і кнопка для завантаження чергового повідомлення.

Одержання одного листа:

procedure Tform1.Button1Click(Sender: Tobject);

begin

Pop3.Host:='mail.58r.ru'; // адреса поштового сервера

Pop3.Port:=110; // порт по якому здійснюватиметься підключення

Pop3.Username:='test+58r.ru'; // Логін користувача

Pop3.Password:='12345666'; // пароль користувача

Idmessage.Clear; // очищення буфера для повідомлення

Pop3.Connect; // підключення по протоколу Pop3, по настройках в компоненті Idpop3, з ім'ям Pop3

Memo1.Clear; // очищення компоненту memo для відображення тексту листа.

Pop3.Retrieve(1,idmessage); // отримання одного повідомлення

Memo1.Lines.AddStrings(Idmessage.Body); // передача повідомлення з компоненту Idmessage в memo

Pop3.Delete(1); // видалення з сервера, отриманого повідомлення

Pop3.Disconnect; // розривши зв'язки

end; Зазвичай потрібно завантажити декілька повідомлень, все що є на сервері. Я вирішив обмежитися 10 листами, щоб не ускладнювати код. Отримувані повідомлення зберігаються в тій же теці що і поштова програма.

Отримання 10 листів:

procedure Tform1.Button2Click(Sender: Tobject);

label f;

var

mailcicl:integer; // лічильник одержуваних листів

addr:string; // тека в якій зберігатимуться одержувані листи

begin

Pop3.Host:='mail.58r.ru'; // адреса поштового сервера

Pop3.Port:=110; // порт, по якому здійснюватиметься підключення

Pop3.Username:='test+58r.ru'; // Логін користувача

Pop3.Password:='12345666'; // пароль користувача

addr:=extractfilepath(Application.ExeName); // отримання адреси теки, в якій знаходитися наша програма

Pop3.Connect; // підключення до сервера

for mailcicl:=1 to 10 do // цикл одержання листів

begin

if Pop3.CheckMessages<1 then goto f ; // Якщо листів немає, то вийти із циклу

Idmessage.Clear; // очищення буфера для повідомлення

Memo1.Clear; // очищення компоненту Memo для відображення тексту листа.

Pop3.Retrieve(1,IDMessage); // отримання одного повідомлення

Memo1.Lines.AddStrings(Idmessage.Body); // передача повідомлення з компоненту IDMessage в Memo

Memo1.Lines.SaveToFile(addr+inttostr(mailcicl)+'.txt'); // збереження листа в теці, де знаходиться наша програма

Pop3.Delete(mailcicl); // видалення листа на сервері

end;

f: // мітка виходу з циклу

Pop3.Disconnect; // розривши з'єднання з сервером end;

Кожне повідомлення має атрибути - це майл відправника, тема повідомлення, важливість і інші елементи.

Одержання листа з атрибутами:

procedure Tform1.Button3Click(Sender: Tobject);

var

i,numposts: Integer;

begin

Pop3.Host:='mail.58r.ru'; // адреса поштового сервера

Pop3.Port:=110; // порт по якому здійснюватиметься підключення

Pop3.Username:='test+58r.ru'; // логін користувача

Pop3.Password:='12345666'; // пароль користувача

Idmessage.Clear; // очищення буфера для повідомлення

Pop3.Connect; // підключення по протоколу Pop3, по настройках в компоненті Idpop3, з ім'ям Pop3

Memo1.Clear; // очищення компоненту memo для відображення тексту листа.

Pop3.Retrieve(1,idmessage); // отримання одного повідомлення

Memo1.Lines.AddStrings(Idmessage.Body); // передача повідомлення з компоненту Idmessage в memo

// вивід в компоненти Label інформації про повідомлення.

Label1.Caption := Idmessage.From.Text;

Label2.Caption := Idmessage.Recipients.EmailAddresses;

Label3.Caption := Idmessage.CCList.EMailAddresses;

Label4.Caption := Idmessage.Subject;

Label5.Caption := Formatdatetime('dd mmm yyyy hh:mm:ss', Idmessage.Date);

Label6.Caption := Idmessage.ReceiptRecipient.Text;

Label7.Caption := Idmessage.Organization;

Pop3.Delete(1); // видалення з сервера, отриманого повідомлення

Pop3.Disconnect; // розривши зв'язки

end;

Відправка пошти здійснюється по протоколу SMTP, компонент IDSMTP, його можна знайти на вкладці Indy Clients. У даному прикладі відправка пошти здійснюватиметься після авторизації сервері, лист відправляється з майла test@58r.ru на майл test@58r.ru .

Відправка одного листа:

procedure Tform1.Button4Click(Sender: Tobject);

begin

SMTP.Host:='mail.58r.ru'; // адреса поштового сервера

SMTP.Port:=25; // порт по якому здійснюватиметься підключення

SMTP.Username:='test+58r.ru'; // логін користувача

SMTP.Password:='12345666'; // пароль користувача

SMTP.AuthenticationType:=atLogin; // тип підключення до сервера - з авторизацією

with Idmessage do

begin

Body.Assign(Memo1.Lines); // передача даних з memo в компонент Idmessage, для подальшої відправки

From.Text := 'test@58r.ru'; // майл відправника листа

Recipients.EMailAddresses := 'test@58r.ru'; // майл одержувача листа

Subject := 'Programmersclub.ru'; // тема листа

end;

SMTP.Connect; // з'єднання з поштовим сервером

try

showmessage('Відбулося підключення до сервера'); // повідомлення про вдале підключення до сервера

SMTP.Send(Idmessage); // відправка листа на сервер

finally

SMTP.Disconnect; // розривши з'єднання

end; end;

Завдання: Створити простий поштовий клієнт. Реалізувати інтерфейс користувача. Передбачити відображення відомостей про відправника та теми листа.

Реалізувати завдання згідно варіанту.

Індивідуальне завдання:

  1. Реалізвати можливість вставки графічних «смайликів».
  2. Реалізувати можливість використання різних шрифтів та стилів, кольорів.
  3. Реалізувати можливість перевірки тексту на помилки.
  4. Реалізувати можливість прикріплення файлів.
  5. Реалізувати можливість використання відступів.
  6. Реалізувати можливість використання інтервалів, відступів, нумерації.
  7. Реалізувати можливість надсилати листи на декілька адрес.
  8. Реалізувати статистику листа.
  9. Створити вікно використання шаблонів та підписів на листі
  10. Створити адресну книгу.
  11. Релізувати можливість додавання адресатів до «чорного списку».

Хід роботи

  1. Ознайомитись з теоретичними відомостями викладеними в конспекті лекцій, та теоретичних відомостях.
  2. Отримати допуск до роботи.
  3. Отримати індивідуальне завдання.
  4. Написати програму що вирішує поставлене завдання.
  5. Показати результат викладачеві.
  6. Отримати тестові дані для перевірки програми.
  7. Виконати перевірку програми з тестовими даними.
  8. Скласти та захистити звіт.

Зміст звіту про роботу

1) титульна сторінка;

2) мета роботи;

3) короткі теоретичні відомості;

4) індивідуальне завдання;

5) опис роботи програми;

6) текст програми;

7) результати роботи програми;

8) висновки з виконаної роботи.


ЛАБОРАТОРНА РОБОТА №5

(4 години)

Тема: Створення клієнтського додатку для отримання RSS-новин.

Мета: Отримати та закріпити навички зі створення клієнтських додатків для читання новин з Internet.

Короткі теоретичні відомості:

У кожного з нас є безліч улюблених сайтів, за оновленнями яких постійно доводиться стежити. Добре, коли таких сайтів не сильно багато. Проблема в тому, що у бувалих користувачів Інтернет таких сайтів налічується кілька десятків. Як встежити за кожним з них? Просто і зручно отримувати новини у форматі RSS.

Власники сайтів намагаються завжди все робити на благо користувачів, і стрічка новин в форматі RSS вже давно є стандартом.

Для читання новин у форматі RSS створені програми – RSS-агрегатори. Їм достатньо вказати посилання на стрічку новин, як вони тут же почнуть пильно стежити за оновленнями і показувати всі топіки в зручному вигляді. Багато розробників стали вбудовувати «читалки» RSS у свої браузери. Таким шляхом пішли розробники Opera, FireFox, IE і т.д.

Абревіатура RSS розшифровується як Really Simple Syndication, що в перекладі означає «Дійсно проста доставка». RSS - це формат, який використовується для опублікування новин. Завдяки цьому формату можна оперативно отримувати новини з своїх улюблених порталів, не чекаючи довгого завантаження сайтів. Не варто думати, що формат RSS призначений, лише для публікації новин. Використовуючи дану технологію, можна запросто передавати інформацію з форуму, гостьової книги і т.д.

Вперше про подібну технологію подумала компанія User Land і в 1997 році вопустила свій формат sсripting news. Формат вийшов непоганим, але не прижився. Виною тому стала компанія Netscape, в той час вона виступала законодавцем моди нових Інтернет-технологій, і конкурувати з нею було досить важко.

Пару років потому виходить у світ RSS 0.9, його розробили на основі sсripting news. Цього разу розробником стала сама Netscape. Формат почав поступово вливатися в маси, але далеко влитися не встиг. Багато хто визнав його сильно складним і не зручним, тому Netscape нічого не залишалося, як зайнятися його вдосконаленням. Результатом став випуск версії - 0.9.1. Формат вийшов досить гнучким і в той же час більш простим у використанні. На жаль, і новий реліз не зміг завоювати серця web-розробників. У цей час Netscape вирішує згорнути розробку RSS і зосередити свої зусилля на інших проектах. Звичайно, Netscape не хотіла просто викинути на смітник свої напрацювання, тому, вона передала право на розробку і розвиток цього проекту вже згадуваній компанії - User Land.

User Land активно почали роботу над вдосконаленням формату. Через деякий час розробники представили версію 0.9.2. У той же самий час організація RSS-Dev Working Group, яка бореться за збереження формату версії 0.9, випускає версію 1.0, в яку лягли ідеї версії 0.9. Версія 1.0 почала набирати обертів, але, знову ж, сильного поширення не отримала. Причини цього все ті ж, що і у 0.9.

2002 рік стає золотим роком для технології RSS. Компанія User Land випускає другу версію (2.0) розглянутої технології. Ця версія викликала справжній бум. Багато web-розробників оцінили її привабливість і почали використовувати у своїх проектах. Через рік, в рамках ліцензії Creative Commons, стає доступною специфікація до формату RSS 2.0.

Створення RSS-агрегатора розпочинаємо зі створення у середовищі Delphi форми, вигляд якої показано на рис. 1.

Рисунок 1 – Форма програми

У верхній частині форми розташована панель з керуючими кнопками, трохи нижче DBGrid (необхідний для відображення даних із БД) і в самому низу DBMemo (у ньому буде відображатися текст новини). Описаний приклад буде працювати з базою даних, тому що набагато зручніше зберігати і правити усі новини у БД, ніж мучиться з текстовими файлами. Тим більше, використовуючи БД, завжди можна з легкістю організувати пошук потрібної новини і багато чого ще. У якості бази даних ми будемо використовувати MS Access.

Для створення БД запускаємо MS Access, створюємо нову БД, зберігаємо її куди-небудь і переходимо до створення таблиці в режимі конструктора.

Рисунок 2 – Таблиця БД у режимі конструктора

У таблиці потрібно створити шість полів:

1. id - лічильник, ключове поле (унікальне поле)

2. title - текстовий (заголовок новини)

3. link - текстовий (посилання на новину)

4. desсription - текстовий (поле MEMO)

5. author - текстовий (автор новини)

6. pubDate - текстовий (дата новини, можна було задати як типу Дата / Час, але щоб не мучиться з перетворенням дати, вказуємо текстовий).

Зберігаємо таблицю під назвою, наприклад, rss. На цьому закриваємо Acсess і повертаємось до Delphi. Розміщуємо на формі компонент AdoTable (ADO) і DataSource (Data Access). У властивості DataSet компонента DataSource вибираємо ADOTable. Тепер прийшла черга центрового компоненту при роботі з БД - ADOTable. Двічі клікаємо по властивості ConnectionString. З'явиться віконце, в якому потрібно натиснути кнопку «Build». На екрані відобразиться форма, в ній потрібно налаштувати підключення з БД (рис. 3).

Рисунок 3 – вікно налаштування підключення до БД

 

Спочатку переходимо на закладку «Постачальник даних» і серед провайдерів знаходимо "Microsoft Jet 4.0 OLE DB Provider". Виділяємо і тиснемо "Далі". У полі вибору БД вводимо ім'я або шлях до створеної БД. Встановлюємо прапорець «Порожній пароль», що необхідно для того, щоб постійно не з’являлося віконце з проханням введення пароля. На цьому налаштування підключення до БД завершено.

Повертаємось до форми виділяємо компоненти DbGrid і DbMemo. В інспекторі об’єктів шукаємо властивість DataSource і вибираємо в ньому DataSource1. Тепер ці компоненти пов'язані з таблицею, а значить, у них будуть відображатися дані з БД. Тепер все готово для того, щоб встановити активність таблиці. Вибираємо ADOTable, у властивості TableName вибираємо таблицю, властивість Active виставляємо в true.

У DbGrid повинні з'явитися колонки з іменами створених полів. Відображати всі поля в DbGrid не потрібно, тому двічі клікаємо по компоненті ADOTable і у вікні натискаємо Ctrl + F (можна просто клікнути правою клавішею миші в області вікна і вибрати «AddAllFields»). Вікно заповниться іменами полів. Якщо виділити будь-яке ім'я поля, його властивості відобразяться в об'єктних інспектора. Найбільшої уваги заслуговують:

DisplayLabel - назва, яке буде відображатися в заголовку колонки DbGrid.

DisplayWidth - ширина колонки. Типово ширина колонки в DbGrid дорівнює розміру поля. У більшості випадку це не зручно, тому краще вказати розмір в ручну.

Name - ім'я для доступу до поля.

Visible - видимість поля.

Імпортуємо RSS

Для імпорту новин доведеться відкрити файл з новинами і пропарсити його, витягуючи інформацію про новини. Назви найбільш важливих елементів формату rss було описано, тому, в принципі, можна написати парсер самостійно. Інший варіант рішення даної задачі передбачає використання якогось готового xml-парсера. Їх досить багато, тому є з чого вибирати. Для нашого прикладу скористаємося розробкою від Microsoft – MSXML. Модуль для роботи з даними парсером вже є у складі Delphi, тому не потрібно нічого зайвого качати і встановлювати.

Роботи з парсером відбувається через об'єкт XMLDOMDocument. Об'єкт має безліч методів, найбільш важливі їх них наступні:

Load (url) Завантажує xml документ

LoadXML (xmlString)

Save (targerStr) Зберігає документ у файл

CreateElement (name) Додавання нового елемента

CreateTextNode (text) Запис тексту в документи / елемент

CreateAttribute (name) Установка атрибутів для елементу

SelectSingleNode (patternString) Посилання на об'єкт типу IXMLDOMNodeList

CloneNode (deep) Копіювання поточного елемента

Код імпорту новин з файлу приведений в лістингу 2. Перед його реалізацією потрібно не забути підключити модуль MSXML і ActiveX.

var

_rss_doc: IXMLDOMDocument;

_node: IXMLDOMNode;

i: Integer;

begin

if not (openDialog1.Execute) then Exit;

/ / Ініціалізція

_rss_doc: = CoDomDocument.Create;

_rss_doc.async: = false;

/ / Завантажуємо документ

_rss_doc.load (OpenDialog1.FileName);

/ / Якщо виникла помилка, то показуємо повідомлення

if _rss_doc.parseError.errorCode <> 0 then

begin

ShowMessage ('При завантаженні файл сталася помилка!' + # 13 # 10 +

'Код помилки:' + IntToStr (_rss_doc.parseError.errorCode) + # 13 # 10 +

'Текст помилки:' + _rss_doc.parseError.reason + # 13 # 10 +

'Рядок з помилкою:' + IntToStr (_rss_doc.parseError.line) + # 13 # 10 +

'Символ у рядку з помилкою:' + IntToStr (_rss_doc.parseError.linepos));

CoUnInitialize;

Exit;

end;

/ / Отримуємо доступ до елементу rss

_node: = _rss_doc.selectSingleNode ('/ / rss');

/ / У циклі отримуємо кожну новину

for i: = 0 to _node.selectNodes ('/ / item'). length-1 do

begin

try

adotable1.Insert;

title.value: = _node.selectnodes ('/ / item'). item [i]. selectSingleNode ('title'). Text;

link.value: = _node.selectnodes ('/ / item'). item [i]. selectSingleNode ('link'). Text;

description.Value: = _node.selectnodes ('/ / item'). item [i]. selectSingleNode ('description'). Text;

pubDate.Value: = _node.selectnodes ('/ / item'). item [i]. selectSingleNode ('pubDate'). Text;

author.Value: = _node.selectnodes ('/ / item'). item [i]. selectSingleNode ('author'). Text;

adotable1.Post; adotable1.Post;

except

end;

end;

 

Перед тим, як почати аналізувати дані, потрібно ініціалізувати об'єкт типу IXMLDomDocument. В описаному випадку це змінна _rss_doc. Ініціалізація відбувається стандартним способом – за допомогою виклику методу Create у співкласу CoDomDocument. Після ініціалізації необхідно відключити асинхронний режим. Тепер треба спробувати виконувати саму завантаження. Завантаження виконується за допомогою методу load. Як параметр йому потрібно передати ім'я файлу, який і буде завантажений.

Завантаживши файл, парсер почне його перевіряти на коректність. У разі знаходження помилок, процес парсингу перерветься і нічого не залишиться робити, як показати повідомлення про помилку, звільнити виділену пам'ять і перервати подальше виконання процедури.
При виникненні помилки є можливість показати додаткові відомості, які допоможуть виправити документ і спробувати завантажити його знову. В якості відомостей показується код помилки (parseError.errorCode), текст помилки (parseError.reason), номер рядка з помилкою (parseError.line) і символ у рядку, з якого починається помилка (parseError.linepos). Знаючи цю інформацію, легко знайти і виправити помилку.

Нехай ніяких помилок не виникло і це значить, що можна починати витягувати новини. У змінну _node отримується посилання на елемент. Для отримання посилання використовується метод SelectSingleNode.

_node: = _rss_doc.selectSingleNode ('/ / rss');

В якості єдиного параметра йому потрібно передати ім'я елемента. Отримавши батьківський елемент, ми запросто зможемо звернутися до будь-якого дочірньому. Згадай структуру rss файлу. Усі наявні елементи / теги якраз і є дочірніми по відношенню до.

Кожна новина в rss - це окремий блок. Щоб дізнатися кількість певних елементів у xml документі, потрібно заглянути у властивість length. Наприклад, щоб подивитися, скільки всього в документі елементів title, варто звернутися до length таким чином:

_node.selectNodes ('/ / title'). length

Таким же способом можливо дізнатися, скільки всього в документі елементів. Знаючи їх кількість, легко написати цикл, в якому реалізується послідовний перебір всіх елементів та отримання інформації, вкладеної у них.

Після запуску циклу починається читання самих новин та їх подальше їх збереження. Оскільки всі дані зберігаються в базі даних, то перед тим як в неї щось додати, необхідно викликати метод Insert таблиці:

ADOTable1.Insert;

Викликавши цей метод, в таблиці створюється новий порожній запис, і користувачеві залишається лише заповнити всі поля. Як значення для поля title (заголовок) присвоюємо вміст елемента title поточного елемента item.

_node.selectnodes ('/ / item'). item [i]. selectSingleNode ('title'). Text;

Інші поля отримують значення тим же способом. Коли всі поля заповнилися, бажано зберегти внесені в таблицю зміни. Для цього використовується метод post компонента ADOTable.

Експорт новин в RSS

Експорт новин з бази у файл реалізувати також за допомогою стандартного парсера. Для цього потрібно розглянути наступні методи: CreateElement(), CreateTextNode (), CreateAttribute(), CreateNode().

В описаному прикладі експорт новин організовано простішим способом. Найбільш важливі моменти коду наведені в лістингу 3. Весь процес організований на стандартних функціях завантаження / збереження тексту у файл. Єдине, на що варто звернути увагу, так це на перебір всіх записів в таблиці БД. Кількість записів зберігається у властивості RecordCount таблиці. Перед тим, як перебирати записи, потрібно встановити курсор на найперший. Це робиться за допомогою методу First компонента ADOTable.

Після читання значень всіх полів чергового запису потрібно пересунути курсор, інакше ми постійно будемо отримувати одні й ті ж значення. Перехід на наступний запис здійснюється методом Next все того ж ADOTable.

var

_header: string;

_bottom: string;

_rss_file: TStringList;

_temp: Widestring;

i: integer;

begin

_header: = '<? xml version = "1.0" encoding = "windows-1251"?>' + # 13 # 10 +

'<rss Version="2.0">' + # 13 # 10 +

'<channel>' + # 13 # 10 +

'<title> Новини мого супер порталу </ title>' + # 13 # 10 +

'<link> Http://vr-online.ru </ link>' + # 13 # 10 +

'<description> Супер-пупер популярний канал </ description>' + # 13 # 10 +

'<lastBuildDate> Sun, 05 Aug 2007 7:30:01 +0400 </ lastBuildDate>' + # 13 # 10 +

'<ttl> 1 </ ttl>';

 

adoTable1.First;

for i: = 0 to adoTable1.RecordCount-1 do

begin

_temp: = '<item>' + # 13 # 10 +

'<title>' + ClearText (title.AsString) + '</ title>' + # 13 # 10 +

'<link>' + ClearText (link.AsString) + '</ link>' + # 13 # 10 +

'<description>' + ClearText (description.AsString) + '</ description>' + # 13 # 10 +

'<author>' + Author.AsString + '</ author>' + # 13 # 10 +

'<pubDate>' + PubDate.AsString + '</ pubDate>' + # 13 # 10 +

'</ Item>';

_rss_file.Add (_temp);

adoTable1.Next;

end;

Рисунок 4 – Результати роботи

Завдання:

  1. Створити RSS-клієнт та реалізувати відкриття новин.




©2015 www.megapredmet.ru Все права принадлежат авторам размещенных материалов.