Файл: Разработка клиентского приложения передачи электронной почты с применением протоколов SMPT и UDP на платформе Win32.pdf
Добавлен: 01.04.2023
Просмотров: 55
Скачиваний: 2
Таблица 2. Коды ответа SMTP и их значение
Код |
Значение |
211 |
Ответ о состоянии системы или помощь. |
214 |
Сообщение-подсказка (помощь) |
220 |
<имя_домена> служба готова к работе |
221 |
<имя_домена> служба закрывает канал связи |
250 |
Запрошенное действие почтовой транзакции успешно завершилось |
251 |
Данный адресат не является местным; сообщение будет передано по маршруту <forward-path> |
354 |
Начинай передачу сообщения. Сообщение заканчивается комбинацией CRLF-точка-CRLF |
421 |
<имя_домена> служба недоступна; соединение закрывается |
450 |
Запрошенная команда почтовой транзакции не выполнена, так как почтовый ящик недоступен |
451 |
Запрошенная команда не выполнена; произошла локальная ошибка при обработке сообщения |
452 |
Запрошенная команда не выполнена; системе не хватило ресурсов |
500 |
Синтаксическая ошибка в тексте команды; команда не опознана |
501 |
Синтаксическая ошибка в аргументах или параметрах команды |
502 |
Данная команда не реализована |
503 |
Неверная последовательность команд |
504 |
У данной команды не может быть аргументов |
550 |
Запрошенная команда не выполнена, так как почтовый ящик недоступен |
551 |
Данный адресат не является местным; попробуйте передать сообщение по маршруту <forward-path> |
552 |
Запрошенная команда почтовой транзакции прервана; дисковое пространство, доступное системе, переполнилось |
553 |
Запрошенная команда не выполнена; указано недопустимое имя почтового ящика |
554 |
Транзакция не выполнена |
Промежуточные агенты
Термин "маршрут доставки" (forward-path) служит для того, чтобы отличать почтовый ящик (mailbox), имя которого абсолютно, от пути (он может быть различным), по которому следует почта. Предположим, что мы хотим доставить два почтовых сообщения на один и тот же сетевой компьютер. Оба сообщения имеют один и тот же адрес, однако не обязательно будут следовать по одному и тому же маршруту. Точно так же, если на пришедшие сообщения выдаются ответы, они не обязательно будут следовать по указанному обратному маршруту (reverse-path). Как правило, конкретный маршрут для почты выбирается системным администратором. Чтобы направить почту по нужному пути, используются значения маршрута доставки и обратного маршрута, в которых указываются промежуточные агенты (relay agents). Промежуточный агент доставки - это МТА, так называемый почтовый хаб (mail hub), настроенный на передачу транзитной почты. Чтобы доставить сообщение, местный агент пользователя (UA) передает его местному МТА, который, в свою очередь, передает его промежуточному агенту МТА. В следующем примере Smith@usc.edu является почтовым ящиком, a HOSTI, HOST2 и HOST3 - промежуточными агентами:
MAIL FROM:<@HOSTI, @HOST2, @HOST3:Smith@usc.edu>
В наше время промежуточные агенты присутствуют практически во всех сетях, входящих в Internet. На рис.6 приведена типичная конфигурация почтовой системы Internet с участием промежуточных агентов.
Чтобы упростить процесс конфигурации почтовой системы, в локальной сети устанавливается один компьютер, служащий промежуточным агентом (relay host). Вся почта пользователей попадает сначала на него. Затем этот компьютер рассылает сообщения по Internet. Кроме всего прочего, такой компьютер может служить защитой фирмы от взломщиков-хакеров из Internet. Ограничивая общение локальной сети с внешним миром до уровня почты, организация сводит до минимума риск нежелательного вторжения в свои собственные системы.
Кроме того, администрировать и защищать в этом случае приходится единственный компьютер. SMTP в состоянии послать сообщение непосредственно с компьютера пользователя на компьютер адресата в том случае, если между ними существует прямое почтовое соединение. К сожалению, это далеко не всегда так. Как правило, между двумя компьютерами находится один или несколько промежуточных агентов. Чтобы обеспечить доставку, в почтовом сообщении нужно указать имя компьютера-получателя и точное наименование почтового ящика. Аргументом команды MAIL является обратный маршрут, включающий имя источника сообщения и имена всех промежуточных агентов. Аргумент команды RCPT - маршрут доставки, содержащий имя получателя сообщения. Обратный маршрут описывает путь, который прошло сообщение, тогда как маршрут доставки идентифицирует место назначения. Обратный маршрут используется SMTP, когда нужно передать сообщение о случившейся ошибке или о невозможности доставить сообщение, когда оно уже прошло через промежуточный агент. По мере продвижения сообщения по Internet записи о его маршрутах изменяются. В обязанности системных администраторов входит правильно настраивать местные МТА на передачу сообщений промежуточному агенту, и наоборот, промежуточные агенты на доставку сообщений местным МТА. Если у промежуточного МТА изменится имя, все, что нужно сделать в конфигурации местного МТА - изменить имя компьютера в системе DNS. Другие параметры конфигурации не изменяются. Другими словами, повторим еще раз, что иметь один компьютер для промежуточной доставки - значит, снять с себя значительную часть головной боли по настройке почтовой системы - ведь придется заботиться только об одном компьютере.
Рассмотрим почтовую транзакцию между промежуточными агентами SMTP. До того как сообщение будет передано следующему указанному в маршруте (в поле ТО:) компьютеру, имя данного компьютера удаляется из маршрута доставки и добавляется в начало обратного маршрута. К тому моменту, когда сообщение достигнет пункта назначения, маршрут доставки будет содержать только имя почтового ящика. В RFC 821 приведен пример того, как изменяется содержимое маршрутов по мере обработки почтового сообщения. Когда промежуточный агент А получает почту со следующими аргументами:
FROM: <USERX@HOSTY.ARPA>
TO: <@HOSTA.ARPA, @HOSTB.ARPA: USERC@HOSTD.ARPA>
он переправляет почту сетевому компьютеру В со следующими аргументами:
FROM: <@HOSTA.ARPA: USERX@HOSTY.ARPA> TO: <@HOSTB.ARPA: USERC@HOSTD.ARPA> .
Как видим, промежуточный агент A (HOSTA.ARPA) убрал свое имя из заголовка <ТО:> и добавил в заголовок <FROM:>. Промежуточный агент компьютера В совершит аналогичное действие, и следующим пунктом назначения сообщения будет почтовый ящик USERC на компьютере HOSTD.ARPA.
Примечание: Другими словами, обратные маршруты и маршруты доставки строятся агентами передачи почты по мере прохождения сообщения от одного агента к следующему. Если очередной на пути сообщения SMTP-агент не умеет обслуживать промежуточную доставку, он должен ответить таким же кодом, какой предусмотрен на случай отсутствия местного почтового ящика.
2.5. Разработанные меню и интерфейсы
При запуске программы на экране появляется главное окно программы с элементами управления (Рис. 2.1).
Рис. 2.1. «Главное окно»
Для настройки почтового клиента необходимо нажать на меню «Настройки». В результате, загружается окно настроек (рис. 2.2.).
Рис. 2.2. «Настройки»
Для отправки письма необходимо запустить окно «Написать письмо» (рис 2.3.), нажатием на кнопку «Написать письмо» в меню «Файл».
Рис. 2.3. окно «Написать сообщение»
UDP — User Datagram Protocol
В отличие от TCP UDP — очень быстрый протокол, поскольку в нем определен самый минимальный механизм, необходимый для передачи данных. Конечно, он имеет некоторые недостатки. Сообщения поступают в любом порядке, и то, которое отправлено первым, может быть получено последним. Доставка сообщений UDP вовсе не гарантируется, сообщение может потеряться, и могут быть получены две копии одного и того же сообщения. Последний случай возникает, если для отправки сообщений в один адрес использовать два разных маршрута.
UDP не требует открывать соединение, и данные могут быть отправлены сразу же, как только они подготовлены. UDP не отправляет подтверждающие сообщения, поэтому данные могут быть получены или потеряны. Если при использовании UDP требуется надежная передача данных, ее следует реализовать в протоколе более высокого уровня.
Так в чем же преимущества UDP, зачем может понадобиться такой ненадежный протокол? Чтобы понять причину использования UDP, нужно различать однонаправленную передачу, широковещательную передачу и групповую рассылку.
Однонаправленное (unicast) сообщение отправляется из одного узла только в один другой узел. Это также называется связью "точка-точка". Протокол TCP поддерживает лишь однонаправленную связь. Если серверу нужно с помощью TCP взаимодействовать с несколькими клиентами, каждый клиент должен установить соединение, поскольку сообщения могут отправляться только одиночным узлам.
Широковещательная передача (broadcast) означает, что сообщение отправляется всем узлам сети. Групповая рассылка (multicast)- это промежуточный механизм: сообщения отправляются выбранным группам узлов.
UDP может использоваться для однонаправленной связи, если требуется быстрая передача, например для доставки мультимедийных данных, но главные преимущества UDP касаются широковещательной передачи и групповой рассылки.
Обычно, когда мы отправляем широковещательные или групповые сообщения, не нужно получать подтверждения из каждого узла, поскольку тогда сервер будет наводнен подтверждениями, а загрузка сети возрастет слишком сильно. Примером широковещательной передачи является служба времени. Сервер времени отправляет широковещательное сообщение, содержащее текущее время, и любой хост, если пожелает, может синхронизировать свое время с временем из широковещательного сообщения.
Заголовок UDP гораздо короче и проще заголовка TCP:
Заголовок UDP.
Поле |
Длина |
Описание |
Порт источника |
2 байта |
Указание порта источника для UDP необязательно. Если это поле используется, получатель может отправить ответ этому порту. |
Порт назначения |
2 байта |
Номер почты назначения |
Длина |
2 байта |
Длина сообщения, включая заголовок и данные. |
Контрольная сумма |
2 байта |
Контрольная сумма заголовка и данных для проверки |
UDP – это быстрый протокол, не генерирующий доставки. Если требуется поддержание порядка сообщений и надёжная доставка, нужно использовать TCP. UDP главным образом предназначен для широковещательного и групповой передачи. Протокол UDP определён в RFC 786.
Разработка приложения
Можно выделить основные этапы разработки программного продукта:
1. Этап проектирования интерфейса программы;
2. Этап написание программного кода;
3. Этап доработки, внесения изменений;
4. Этап формирования конечного продукта.
На первом этапе проектирования создается общий интерфейс программного продукта и создается его функциональная поддержка.
Этап задания обучающего материала включает в себя:
· Создание определенного макета программы;
· Создание интерфейса управления;
· Разработка оформления.
В результате проектирования выше изложенной части работы программный продукт должен поддерживать следующие функции:
· Ввод текстовой информации и ее изменение до отправки;
· Быстродействие и удобство пользования интерфейсом.
Этап написания программного кода:
· Выбор и анализ методов написания алгоритма выполнения программы;
· Написание основных функций;
· Внесение исправлений и настройка программы.
Описание программы сервера локальный чат сервер программный
Программа выполняет следующие функции:
· Контролирует подключение пользователей и их количество;
· Получает сообщения от каждого пользователя;
· Передаёт сообщения от одного пользователя в общий чат.
В главной функции сервера задаются настройки сервера, принятие и отправка сообщений всем пользователям чата. Помимо этого, ведется протоколирование всего происходящего и выводится на консоль (Рис. 1).
Рис. 1
Настройки сервера:
server.ai_family = AF_INET;
server.ai_flags = AI_PASSIVE;
server.ai_socktype = SOCK_STREAM;
server.ai_protocol = IPPROTO_TCP;
getaddrinfo(NULL, "8888", &server, &result);
8888 - номер порта, с которым будет работать чат.
Создание потока, в котором происходит отправка сообщений:
CreateThread(NULL, NULL, (PTHREAD_START_ROUTINE)SendMessageToClient, (LPVOID)(ClientCount - 1), NULL, NULL);
Слушающий сокет:
Listen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
bind(Listen, result->ai_addr, result->ai_addrlen);
Следующий метод отвечает за отправку сообщений:
void SendMessageToClient(int ID)
{
char* buffer = new char[1024];
for (;; Sleep(100))
{
memset(buffer, 0, sizeof(buffer));
if (recv(Connections[ID], buffer, 1024, NULL))
{
printf("%s", buffer);
for (int i = 0; i <= ClientCount; i++)
{
send(Connections[i], buffer, strlen(buffer), NULL);
}
}
}
free(buffer);
}