Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
rgz_smit.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
90.62 Кб
Скачать

Завдання на виконання

Завдання1. Створити скрипт на мові програмування PHP який реалізує поштового клієнта, та функціонує за протоколом SMTP з поштовим сервером. При цьому, для відправки поштового повідомлення, якщо цього вимагає сервер, створюваний поштовий клієнт повинен підтримувати механізм авторизації. Створюваний поштовий клієнт повинен бути здатний передавати як текстові повідомлення, так і бінарні дані (вкладення), а також повинен бути здатний реалізовувати розсилку (передачу одних і тих же даних декільком адресатам). Для взаємодії з сервером використовувати технологію сокетів та команди SMTP.

Завдання2. Створити WEB інтерфейс до створеного в попередньому завданні поштовому клієнтову. При цьому передбачити відправку через браузер клієнта для формування поштового повідомлення як текстові дані, так і бінарні дані, створені вручну або отримані з файлів. Передачу даних реалізувати засобами HTTP протоколу. Форматування відображення інформації в браузері реалізувати за допомогою технології CSS.

Додатоки додаток . Відправка листів через smtp за допомогою php

Далі буде розказано, як відправляти пошту через SMTP з авторизацією за допомогою PHP. Розглядати будемо варіант відправки саме з авторизацією, так як SMTP без авторизації в даний момент майже не існує. Для відправки листа через SMTP будемо використовувати можливість роботи php з сокетами. А зараз все це спілкування з сервером переведемо на php. Після кожної передачі команди на сервер, потрібно буде отримувати відповідь від сервера. Для цього створимо функцію, яка буде працювати з відкритим з'єднанням і отримувати відповідь від сервера.

<?php function get_data($smtp_conn) {   $data="";   while($str = fgets($smtp_conn,515))  {     $data .= $str;     if(substr($str,3,1) == " ") {

break;

};   };   return $data; }; ?>

Функція повертає рядок відгуку. Тут $ smtp_conn являє собою дескриптор сокета, створений функцією fsockopen (). Максимальний розмір рядка відгуку, включаючи <CRLF> 512 символів. При цьому код відгуку міститься в перших трьох символах рядка.

Далі створюємо мінімальне число необхідних заголовків листа.

<? php $header="Date: ".date("D, j M Y G:i:s")." +0700\r\n";  ?>

Date: дата і час відправлення листа; вони записуються в стандартному форматі - тиждень, день, місяць, рік (2 цифри), час, часова зона.

<?php

$header.="From: <login@mail.ru>\r\n"; 

?>

From: ім'я відправника та його зворотня адреса. Зазвичай вказується поштова адреса відправника у форматі ім'я_відправника @ домен.

<?php $header.="Message-ID: <172562218.".date("YmjHis")."@mail.ru>\r\n"; ?>

Message-Id: Унікальний ідентифікатор повідомлення, який комп'ютер-відправник присвоїть йому автоматично.

<?php

$header.="To: <asd@qwe.ru>\r\n";

?>

To: адреса одержувача. Зазвичай вказується поштову адресу одержувача в форматі імя_получателя @ домен.

<?php $header.="MIME-Version: 1.0\r\n";

?>

<?php $header.="Content-Type: text/plain; charset=windows-1251\r\n"; $header.="Content-Transfer-Encoding: 8bit\r\n"; ?>

Таким чином, змінна $ header містить всі необхідні заголовки. Тепер створимо текст листа.

<?php

$text="hello, communication checks.";

?>

Для відкриття з'єднання з SMTP сервером використовуємо наступну функцію

<?php

$smtp_conn = fsockopen("smtp.mail.ru", 25,$errno, $errstr, 10);

?>

Яка ініціює потокове з'єднання в домені Internet (AF_INET, використовуючи TCP або UDP) або Unix (AF_UNIX). Для домену Internet - відкриває сокет з'єднання TCP з hostname (smtp.mail.ru) через порт port (25 для SMTP сервера). Hostname може бути в цьому випадку або повним кваліфікованим ім'ям домену, або IP-адресою. Для UDP необхідно явно специфікувати протокол шляхом додавання до hostname префікса 'udp :/ /'. Необов'язковий timeout (10) може використовуватися для установки таймауту в секундах для системного виклику connect.

Після відкриття з'єднання читаємо відповідь від сервера

<?php

$data = get_data($smtp_conn);

?>

Ну а тепер починаємо запускати всі команди, взаємодії з SMTP сервером. І після кожного введення команди зчитуємо відповідь від сервера.

<?php fputs($smtp_conn,"EHLO vasya\r\n"); $data = get_data($smtp_conn); ?>

Наступні команди призначені для авторизації користувача при відправленні пошти через пересильщіков. Логін (login) і пароль (password) повинні бути зареєстровані в поштовому сервері пересильщіков. Зауважимо, що логін і пароль повинні передаватися в кодуванні base64. Для цього використовується функція base64_encode.

<?php fputs($smtp_conn,"AUTH LOGIN\r\n"); $data = get_data($smtp_conn); ?>

<?php fputs($smtp_conn,base64_encode("login")."\r\n"); $data = get_data($smtp_conn); ?>

<?php fputs($smtp_conn,base64_encode("password")."\r\n"); $data = get_data($smtp_conn); ?>

Рахуємо кількість символів листа з усіма заголовками, щоб передати якого розміру буде лист

<?php $size_msg=strlen($header."\r\n".$text);  fputs($smtp_conn,"MAIL FROM:<login@mail.ru> SIZE=".$size_msg."\r\n"); $data = get_data($smtp_conn); fputs($smtp_conn,"RCPT TO:<asd@qwe.ru>\r\n"); $data = get_data($smtp_conn); fputs($smtp_conn,"DATA\r\n"); $data = get_data($smtp_conn); fputs($smtp_conn,$header."\r\n".$text."\r\n.\r\n"); $data = get_data($smtp_conn); fputs($smtp_conn,"QUIT\r\n"); $data = get_data($smtp_conn); ?>

Для чого читати відповідь від сервера після кожної команди? Кожен рядок відгуку складається з коду з трьох цифр і текстового пояснення. І після кожного введення команди потрібно знати, прийняв сервер команду чи ні. Визначити код дуже просто, треба просто отримати перші три символи строки

<?php

$code = substr($data,0,3);

?>

Например

<?php

fputs($smtp_conn,"EHLO vasya\r\n"); $code = substr(get_data($smtp_conn),0,3); if($code != 250) {

print "ошибка приветсвия EHLO";

fclose($smtp_conn);

exit;

};

?>

Якщо необхідно відправити один лист багатьом адресатам, то досить використовувати команду RCPT TO кілька разів поспіль, вказуючи в ній email адреси, на які потрібно розіслати лист. Після цього йде DATA і далі лист ... І лист буде розіслано по всіх вказаними адресами. Якщо необхідно відправити кілька різних листів, різним адресатам, тоді робимо так: спочатку йде все стандартно - з'єдналися, авторизувалися, відправили лист і після відправлення листа надсилаємо команду не вихід, а скидання RSET. Ця команда скидає все, що було введено в поточному сеансі, і після цього можна починати формувати і відправляти наступний лист. Починаємо відправляти знову

MAIL FROM: .......

RCPT TO: ...... і т.д.

Тобто, формуємо з самого початку нового листа. Після завершення відправки можна знову ввести RSET і сформувати третій лист, четверте і т.д. Ну і в самому кінці вже ставимо QUIT. Велике число листів містить не тільки текст, а вимагає вкладення бінарних даних. Наприклад, при відправці в якості поштового повідомлення документ у форматі MSWORD або PDF. При цьому будуть змінюватися заголовки листа, а вміст вкладених файлів повинно кодуватися. На попередньому прикладі вкладемо два файли. Для цього потрібно внести поправку в заголовки.

Content-Type: text/plain; charset=windows-1251 Content-Transfer-Encoding: 8bit

Замінюємо ось ці два заголовки на

Content-Type: multipart/mixed; boundary="----------A4D921C2D10D7DB"

Цей заголовок означає, що в листі будуть різні типи даних, і роздільник між цими даними буде "---------- A4D921C2D10D7DB". Роздільник може бути будь-яким, головне правило, щоб роздільник (мітка) починався з "-" і щоб така послідовність символів не зустрічалася в тексті листа. Закінчення всіх частин листа також позначається цим же роздільником, але з додаванням символів "-" в кінці. Наприклад, у вище наведеному прикладі це буде "---------- A4D921C2D10D7DB -". Файли будуть вставлятися в тіло листа перекодованими, з використанням кодування base64. Підготував дві текстові змінні, що містять файли в кодованому вигляді.

<?php $file="path/1.jpg"; $fp = fopen($file, "rb"); $code_file1 = chunk_split(base64_encode(fread($fp, filesize($file)))); fclose($fp); ?>

Зверніть увагу, як читається і кодується файл. Разом з кодуванням він розбивається на рядки по 76 символів, щоб не було довгої строки, так як довжина строки в поштовому форматі обмежена. Таким чином, можна вставити не лише jpg, а й будь бінарний файл. Отже, один файл готовий до вкладення і зараз створимо ще один файл, текстовий. Текстовий файл необов'язково читати з диска, можна створити його відразу з тексту.

<?php

$code_file2=base64_encode("Hi, this is like a second file "); ?>

Ось таким чином створили другу текстову змінну, яка містить текстові дані в base64. Тепер тіло листа буде мати наступний вигляд.

<?php $text="------------A4D921C2D10D7DB Content-Type: text/plain; charset=windows-1251 Content-Transfer-Encoding: 8bit hello, communication checks. ------------A4D921C2D10D7DB Content-Type: application/octet-stream; name=\"1.jpg\" Content-transfer-encoding: base64 Content-Disposition: attachment; filename=\"1.jpg\" ".$code_file1." ------------A4D921C2D10D7DB Content-Type: application/octet-stream; name=\"2.txt\" Content-transfer-encoding: base64 Content-Disposition: attachment; filename=\"2.txt\" ".$code_file2." ------------A4D921C2D10D7DB-- "; ?>

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

Content-Type: text/plain; charset=windows-1251 Content-Transfer-Encoding: 8bit

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

------------A4D921C2D10D7DB Content-Type: application/octet-stream; name="1.jpg" Content-transfer-encoding: base64 Content-Disposition: attachment; filename="1.jpg"

Ось поставлений роздільник, це означає, що почалася наступна частина. Так само треба вказати які дані будуть в цій частині. Дані заголовки показують, що зараз піде кодований в base64 файл з ім'ям 1.jpg. Після заголовків ставимо порожній рядок, і вставляємо кодований текст $ code_file1. Потім знову ставимо роздільник і знову вказуємо заголовки, що означає, що піде ще один файл. І т.д. Так можна вкладати файли ще і ще. Коли вкладення закінчені, потрібно завершити це тим же самим роздільником, тільки в кінці повинно бути "-", це буде ознакою закінчення вкладень. Ну а далі, як завжди, вставляємо це все в відправку на сервер

<?php

fputs($smtp_conn,$header."\r\n".$text."\r\n.\r\n");

?>

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]