Отправка сообщений делфи. Отправка почты средствами Delphi. Использование сообщений внутри приложения


ВМС Франции располагают вторым по величине и самым боеспособным авианосцем в Европе "Шарль де Голль". Полное водоизмещение корабля - 42 тыс. тонн, на его борту может базироваться до 40 летательных аппаратов, корабль снабжен атомной силовой установкой. Большими ударными возможностями располагают атомные подводные лодки типа "Триумфан", всего флот располагает четырьмя такими субмаринами.


"Триумфаны" несут баллистические ракеты M4S с дальностью стрельбы 6000 км. В ближайшей перспективе их заменят ракетами М51 с дальностью стрельбы более 10 000 км. Кроме того, имеются шесть многоцелевых атомных субмарин типа "Рюби". Всего по данным из открытых источников французский флот насчитывает 98 боевых кораблей и вспомогательных судов.

5. Великобритания

Некогда Великобритания носила гордое звание "Владычица морей", флот этой страны был самым большим и мощным в мире. Теперь же ВМФ Ее Величества лишь бледная тень былого могущества.

HMS Queen Elizabeth. Фото: i.imgur.com


Сегодня в составе королевского флота нет ни одного авианосца. Два, типа "Куин Элизабет", находятся в постройке и должны войти в состав флота в 2016 и 2018 годах. Самое интересное, что на такие важные корабли, как авианосцы, у англичан не хватило средств, поэтому конструкторам пришлось отказаться от бортовой брони и бронированных переборок. Сегодня, согласно данным из открытых источников, ВМС Великобритании насчитывает 77 кораблей .


Самыми грозными единицами флота считаются четыре ПЛАРБ типа "Вэнгард", вооруженные баллистическими ракетами Trident-2 D5, каждая из которых могла быть оснащена четырнадцатью боевыми блоками по 100 кТ каждая. Желая сэкономить, британские военные купили только 58 таких ракет, чего хватило только для трех лодок - по 16 на каждую. Теоретически же каждый "Вэнгард" может нести до 64 ракет, но это неэкономно.


Кроме них, внушительную силу представляют эсминцы типа "Дэринг", подводные лодки типа "Трафальгар" и новейшие типа "Эстьют".

4. Китай

Китайский флот - один из самых многочисленных, в его составе - 495 кораблей различных классов. Самое большое судно - авианосец "Ляонин" водоизмещением 59 500 тонн (бывший советский авианесущий крейсер "Варяг", который был продан Китаю Украиной по цене металлолома).


Также в составе флота есть стратегические ракетоносцы - атомные подводные лодки проекта 094 "Цзинь". Субмарины способны нести 12 баллистических ракет типа Цзюйлан-2 (JL-2) с дальностью действия 8-12 тыс. км.


Много и "свежих" кораблей, например, эсминцы типа 051С, типа "Ланьчжоу", типа "Современный" и фрегаты типа "Цзянкай".

3. Япония

В японском флоте все крупные корабли классифицируются как эсминцы, поэтому среди настоящих эсминцев есть авианесущие корабли (два корабля типа "Хьюга" и два типа "Сиранэ"), крейсеры и фрегаты. Например, два эсминца типа "Атаго" могут похвастаться крейсерским водоизмещением - 10 тыс. тонн.


Но это не самые крупные корабли - в этом году в состав флота войдет 27 000-тонный вертолетоносец типа "Идзумо", еще один будет произведен в 2017 году. Кроме вертолетов, на "Идзумо" могут базироваться истребители F-35B.


Подводный флот Японии, несмотря на отсутствие атомных подводных лодок, считается сильнейшим в мире. Он насчитывает пять ПЛ типа "Сорю", одиннадцать типа "Оясио" и одну "Харусио".


Сейчас Морские силы самообороны Японии насчитывает приблизительно 124 корабля . Эксперты отмечают, что японский флот имеет сбалансированный корабельный состав и представляет собой продуманную до мелочей боевую систему.

2. Россия

Российский флот насчитывает 280 кораблей . Самые грозные - тяжелые крейсеры проекта 1144 "Орлан" водоизмещением 25 860 тонн, их всего три, но огневая мощь этих судов просто потрясающая. Недаром в НАТО эти крейсеры классифицируют как линейные.

Не уступают им по вооружению три других крейсера - проекта 1164 "Атлант", водоизмещением 11 380 тонн. Но самым большим является авианесущий крейсер "Адмирал флота Советского Союза Кузнецов" водоизмещением 61 390 тонн. Этот корабль не только хорошо защищен средствами ПВО, но и бронирован. В качестве брони используется катанная сталь, а противоторпедная трехслойная защита шириной 4,5 м выдерживает попадание 400 кг ТНТ заряда.

Впрочем, и сам флот активно модернизируется: планируется, что до 2020 года Военно-морской флот Российской Федерации получит порядка 54 современных боевых надводных кораблей, 16 многоцелевых подводных лодок и 8 стратегических подводных ракетоносцев проекта "Борей".

1. США

ВМС США обладают крупнейшим флотом в мире, в его составе 275 кораблей , в том числе 10 авианосцев типа "Нимиц", такой внушительной силой не обладает ни одна страна. Именно на флоте в основном базируется военная мощь Соединенных Штатов.


Вскоре дополнить "Нимицы" должны еще более совершенные корабли - авианосцы типа "Джеральд Р. Форд" водоизмещением более 100 000 тонн.

Подводный флот США не менее внушителен: 14 атомных подлодок типа "Огайо", каждая из которых несет по 24 баллистические ракеты "Трайдент-2". Три совершеннейшие подлодки типа "Си Вулф", цена которых была непомерной для США, поэтому от строительства крупной серии было решено отказаться. Вместо них строятся более дешевые ПЛА типа "Вирджиния", пока их в составе флота всего 10 единиц.


Кроме того, в составе ВМС остается 41 ПЛА типа "Лос-Анджелес". Флот США обладает гигантской военной мощью, оспорить которую сегодня вряд ли кому-то под силу.

    Типы подводных лодок ВМС Великобритании - Эта страница информационный список. Ниже представлен список типов и проектов подводных лодок, входящих и входивших в состав Королевского военно морского флота, упорядоченный по классу корабля и периоду истории. Для лодок, имеющих имена… … Википедия

    Список авианосцев ВМС Великобритании - На этой странице помещён список всех авианосцев ВМС Великобритании. Содержание 1 Авианосцы 2 Гидроавианосцы 3 Примечания … Википедия

    Королевские ВМС Великобритании - Royal Navy Королевский военно морской флот Логотип Королевского ВМФ Великобритании Год формирования Страна Великобритания Подчинени … Википедия

    Список подводных лодок ВМС Великобритании - … Википедия

    ВМС Норвегии - Norske Sjøforsvaret Военно морские силы Норвегии Эмблема военно морских сил Норвегии Год формирования Страна Норвегия Подчинен … Википедия

    ВМС Бельгии - Marinecomponent Composante Marine Военно морские силы Бельгии Год формирования 15 января 1831 года Страна Бельгия Подчинение Министерство обороны Бельгии В составе Вооружённые силы Бельгии … Википедия

    ВМС Израиля - חיל הים הישראלי Военно морские силы Израиля Эмблема ВМС Израиля Год формирования 1948 Страна Израиль Подчинение … Википедия

    Флаги ВМС стран Европы - В галерее флагов ВМС стран Европы представлены все флаги военно морских сил независимых государств Европы. Единственная европейская страна имеющая ВМС, но не имеющая флаг ВМС Мальта. Содержание 1 Албания 2 Бельгия 3 Болгария … Википедия

    Военно-морские силы Великобритании - Naval Service Военно морская служба … Википедия

    Классификации кораблей ВМС США - В Соединенных Штатах для обозначения кораблей используется классификация по бортовому номеру (иногда называется бортовой код) англ. Hull number. ВМС Великобритании, как и флоты некоторых европейских стран и стран Содружества (всего 19… … Википедия

Книги

  • ВМС Великобритании. Фрегаты. Часть 2 , Ю. В. Апальков. Вторая часть монографии "ВМС Великобритании. Фрегаты" посвящена эскортным кораблям ВМС этой страны, строившимся с 1964 года по настоящее время и перспективным британским корабля этого класса,… Купить за 2504 руб
  • ВМС Великобритании Минно-тральные корабли , Апальков Ю.. Эта книга является продолжением серии "Военное кораблестроение. 1945-2020 годы" . В предлагаемой вниманию читателей работе рассматривается история эволюции минно-тральных кораблей ВМС…

Зачастую, программы на delphi используют средствами email. В этой статье будет полностью рассказано, как отправляется ваше письмо другому пользователю. при помощи delphi. При этом, будем использовать только стандартные компоненты делфи.

Для начала создадим новый проект и назовём его \»Отправка писем средствами delphi\». Затем, на форму необходимо перенести несколько компонентов 1x Memo, 3x Edit, 2x Botton, а также необходимо перенести IdSMTP, IdAntiFreeze, IdMessage. Далее, на событие onclick любой кнопки пишем:

//выбираем SMTP сервер. В данный момент стоит yandex. IdSMTP1.Host:= "smtp.yandex.ru"; //ваш логин (для некоторых необходимо писать с доменом). IdSMTP1.Username:= "[email protected]"; //пароль от почты. IdSMTP1.Password:= "qwerty123"; //порт, рекомендуем использовать 587. IdSMTP1.Port:=587; //в Edit2 будет вписываться тема письма. IdMessage1.Subject:= Edit2.Text; //в Edit1 будет адрес получателя. IdMessage1.Recipients.EMailAddresses:= Edit1.Text; //ваш email с которого идёт отправка. IdMessage1.From.Address:= "[email protected]"; //в memo1 будет текст который вы ходите послать. IdMessage1.Body.Text:= memo1.Text ; //в Edit3 будет ваша электронная подпись (Имя). IdMessage1.From.Name:= Edit3.Text; //соединяемся IdSMTP1.connect; //отправляем IdSMTP1.Send(IdMessage1); //отсоединяемся IdSMTP1.Disconnect;

Если IdMessage отображает знаки вопроса

Данный баг связан с тем, что Вы вписываете русские буквы, а компонент memo не может их грамотно прочитать, для этого необходимо указать кодировку Utf8.

// устанавливаем кодировку IdMessage1.Charset:="UTF-8"; // переводим текст в нужную кодировку IdMessage1.Body.Text:=UTF8Encode(memo1.text);

При разработке приложений может возникнуть ситуация, при которой приложению потребуется послать сообщение либо самому себе, либо другому пользовательскому приложению. У некоторых предыдущее утверждение вызовет недоумение: зачем при ложению посылать сообщение самому себе, если можно просто вызвать соответствую щую процедуру? Это хороший вопрос, и на него существует несколько ответов. Во первых, использование сообщений представляет собой механизм поддержки реального полиморфизма, поскольку не требует наличия каких либо знаний о типе объекта полу чающего сообщение. Таким образом, технология работы с сообщениями имеет ту же мощь, что и механизм виртуальных методов, но обладает существенно большей гибко стью. Во вторых, сообщения допускают необязательную обработку - если объект получатель не обработает поступившее сообщение, то ничего страшного не произой дет. И, в третьих, сообщения позволяют осуществлять широковещательное обращение к нескольким получателям и организовывать параллельное прослушивание, что доста точно трудно реализовать с помощью механизма вызова процедур.

Использование сообщений внутри приложения

Заставить приложение послать сообщение самому себе очень просто - достаточно либо воспользоваться функциями интерфейса API Win32 SendMessage() или Post- Message(), либо методом Perform(). Сообщение должно обладать идентификато ром в диапазоне от WM_USER+100 до $7FFFF (этот диапазон Windows резервирует для сообщений пользователя). Например:const

SX_MYMESSAGE = WM_USER + 100;

SomeForm.Perform(SX_MYMESSAGE, 0, 0);

SendMessage(SomeForm.Handle, SX_MYMESSAGE, 0, 0);

PostMessage(SomeForm.Handle, SX_MYMESSAGE, 0, 0);

Затем, для перехвата этого сообщения, создайте обычную процедуру обработчик, выполняющую в форме необходимые действия:

TForm1 = class(TForm)

procedure SXMyMessage(var Msg: TMessage); message SX_MYMESSAGE;

procedure TForm1.SXMyMessage(var Msg: TMessage);

MessageDlg(‘She turned me into a newt!’,

mtInformation, , 0);

Как видно из примера, различия в обработке собственного сообщения и стандарт ного сообщения Windows невелики. Они заключаются в использовании идентифика торов в диапазоне от WM_USER+100 и выше, а также в присвоении каждому сообще нию имени, которое каким то образом будет отражать его смысл.

Никогда не посылайте сообщений, значение WM_USER которых превосходит $7FFF, ес- ли не уверены абсолютно точно, что получатель способен правильно обработать это сообщение. Поскольку каждое окно может независимо выбирать используемые им значения, весьма вероятно появление трудноуловимых ошибок, если только заранее не составить таблицы идентификаторов сообщений, с которыми будут работать все отправители и получатели сообщений.

Обмен сообщениями между приложениями

При необходимости организовать обмен сообщениями между двумя или более приложениями в них следует использовать функцию API RegisterWindowMessage(). Этот метод гарантирует, что для заданного типа сообщений каждое приложение бу дет использовать один и тот же номер сообщения (message number).

Функция RegisterWindowMessage() принимает в качестве параметра строку с за

вершающим нулевым символом и возвращает для нового сообщения идентификатор вдиапазоне $C000 – $FFFF. Это означает, что вызова данной функции с одной и той же строкой в качестве параметра в любом приложении будет достаточно, чтобы га рантировать одинаковые номера сообщений во всех приложениях, принимающих участие в обмене. Еще одно преимущество такой функции состоит в том, что система гарантирует уникальность идентификатора, назначенного любой заданной строке. Это позволяет посылать широковещательные сообщения всем существующим в сис теме окнам, не опасаясь нежелательных побочных эффектов. Недостатком данного метода является некоторое усложнение обработки подобных сообщений. Суть заклю чается в том, что идентификатор сообщения становится известным только при рабо те приложения, поэтому использование стандартных процедур обработки сообщений оказывается невозможным. Для работы с подобными сообщениями потребуется пе реопределить стандартные методы WndProc() или DefaultHandler() элементов управления либо соответствующие процедуры класса окна.

НА ЗАМЕТКУ

Число, возвращаемое функцией RegisterWindowMessage(), создается динамически и может принимать различные значения в разных сессиях Windows, а значит, не может быть определено до момента выполнения программы.

Широковещательные сообщения

Любой класс, производный от класса TWinControl, позволяет с помощью метода Broadcast() послать широковещательное сообщение (broadcast message) любому элементу управления, владельцем которого он является. Эта технология используется в тех случа ях, когда требуется послать одно и то же сообщение группе компонентов. Например, чтобы послать пользовательское сообщение по имени um_Foo всем элементам управле ния, принадлежащим объекту Panel1, можно воспользоваться следующим кодом:

Message:= UM_FOO;

где то так

IdTCPClient1.Host:= "127.0.0.1"; IdTCPClient1.Connect;// подключились IdTCPClient1.Socket.WriteLn("command"); // отправили команду command и перевод строки //Ожидаем ответ и закрываем соединение txtResults.Lines.Append(IdTCPClient1.Socket.ReadLn); IdTCPClient1.Disconnect;

в данном случае команда - это просто текст с переводом строки. Это сильно упрощает прием команды с другой стороны (просто ReadLn). В общем же случае нужно придумывать (или использовать готовый) протокол.

выше это был клиент. А теперь сервер. С сервером все немного сложнее. Понятное дело, что для сервера нормально обслуживать не одного клиента, многих. И для этого есть несколько "схем".

    Классическая - один клиент - один поток. Схема проста в кодировании, интуитивно понятна. Хорошо распаралеливается по ядрам. Недостаток - обычно очень сложно создать много потоков, а это ограничивает кол-во клиентов. Для 32битных программ верхний предел где то в районе 1500 (полторы тысячи) потоков на процесс. Но в этом случае накладные расходы на их переключение могут "скушать" весь проц. Именно эта схема используется в indy.

    Вторая классическая - все клиенты на один поток. Эта схема часто более сложна в кодировании, но при правильном подходе позволяет держать 20-30к "медленных пользователей" практически не нагружая ядро. Сильный плюс этой схемы - можно обойтись без мютексов и других примитивов синхронизации. Эту схему использует NodeJS и стандартные классы для работы с сетью в Qt.

    Смешанная. В этом случае создается несколько потоков, каждый с которых обслуживает какое-то кол-во клиентов. Самая сложная в кодировании, но позволяет по максимуму использовать ресурсы железа.

Как это сделано в Indy. Indy tcp сервер для каждого подключения создает отдельный поток (TThread) и дальнейшая работа с клиентом идет в нем. Indy красиво это прячет, оставляя для пользователя только необходимость реализовать метод IdTCPServer.onExecute . Но, как я сказал выше, этот метод запускается в отдельном треде и он у каждого клиента свой личный. Это значит следующее:

  • в этом методе можно позвать sleep и только один клиент будет ждать. Все остальные будут работать (а вот если в обработчике нажатия кнопки позвать sleep, то результат известен)
    • обращаться к глобальным переменным лучше только через примитивы синхронизации.
    • обращаться к элементам gui нужно аккуратно и правильно. Напрямую лучше не делать (некоторые компоненты разрешают обращаться к ним с других потоков, но нужно внимательно читать доки).
    • обращаться к другим клиентам нужно через блокировку (потому что если два потока захотят писать одному и тому же пользователю - ничего хорошего с этого не выйдет).

Рассмотрим очень простой пример. На любой запрос клиента отвечаем тем же и закрываем соединение (такой себе echo сервер).

Procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); var strText: String; begin //Принимаем от клиента строку strText:= AContext.Connection.Socket.ReadLn; //Отвечаем AContext.Connection.Socket.WriteLn(strText); //Закрываем соединение с пользователем AContext.Connection.Disconnect; end;

AContext это специальный объект, который содержит всю необходимую информацию о клиенте. Сам idTcpServer содержит список этих контекстов и к нему можно обратиться. Рассмотрим более сложный бродкаст. То есть, разослать одно сообщение всем

Var Clients: TList; i: integer; begin // защита от дурака:) if not Assigned(IdTCPServer1.Contexts) then exit; // получим список клиентов, и заблокируем его Clients:=IdTCPServer1.Contexts.LockList; try for i:= 0 to Clients.Count-1 do try //LBuffer имеет тип TBytes и содержит подготовленные данные для отправки // но можно и WriteLn использовать. TIdContext(Clients[i]).Connection.IOHandler.Write(LBuffer); except // тут нужно добавить логику. Клиент может отключиться в процессе end; finally // важно! список нужно разблокировать, иначе другие методы не смогут пройти дальше Contexts.LockList IdTCPServer1.Contexts.UnlockList; end; end;

инди содержит BytesToString() и ToBytes() для предобразования String и TIdBytes друг в дружку.

Список блокируется, что бы другие не могли его модифицировать. Иначе сам цикл сильно усложняется. И главное, не забывать разблокировать!

Остался последний вопрос. Как отправить сообщение какому то определенному клиенту. Для этого нужно научиться идентифицировать соединение. Это можно сделать несколькими способами - посмотреть в айпи/порт. Но есть лучше. У IdContext (точнее у его предка idTask) есть свойство Data типа TObject. В него можно записать свой объект и хранить там все нужные данные. Типичный пример использования будет следующий. Когда клиент только подключился - это поле пустое. Когда он прошел проверку имени-пароля - создаем объект (свой), сохраняем имя туда и прописываем в свойство Data. А потом, когда нужно делать цикл по подключенным клиентам, просто вычитываем его. Конечно, если пользователей тысячи, каждый раз просматривать всех пользователей будет накладно. Но как делать это более оптимально - тема другой большой статьи.



Просмотров