Перейти к содержанию
Fire Monkey от А до Я

Евгений Корепов

Пользователи
  • Постов

    738
  • Зарегистрирован

  • Посещение

  • Победитель дней

    100

Весь контент Евгений Корепов

  1. Посмотрите Deployment проекта, конфигурации Debug и Release, возможно в режиме Release не отмечена какая то из библиотек .so
  2. Я знаю как на этом форуме относятся к идеям заставить мобильное устройство что то мониторить круглые сутки - начинаются крики "Ересь! Это не возможно! Сжечь его на костре пока не поздно!" :-) Но я считаю что в нашей области нужно ограничиваться только фантазией и не слушать запретителей и ограничителей. Задача у меня следующая - есть несколько моих приложений мониторинга майнинга криптовалюты, нужно добавить туда возможность мониторить круглые сутки воркеров (на человеческом языке это комп с 5-6 видеокартами, так называемая "ферма", или аппаратный модуль майнинга). В ответ на "сожрет батарею нафик" - одна ферма может зарабатывать от нескольких сотен рублей, до нескольких тысяч долларов в сутки, и понятно что человеку имеющему шанс потерять много денег, лучше узнать вовремя о зависании фермы в 23:15, чем обнаружить это утром и потерять деньги. С ужасной трагедией в виде севшего на 20% больше чем обычно аккумулятора телефона он, после многолетнего посещения психотерапевтов, думаю смирится. Ответ на "Пуши наше все - поднимай сервер, пусть он мониторит и отсылает пуши" - на одном майнинговом пуле может быть несколько тысяч майнеров (людей) и у каждого по несколько десятков или сотен ворекров (ферм). Если проверять с периодичностью в 10 минут, то нужно будет отослать за этот период несколько десятков тысяч запросов, обработать их (хранить историю каждого). Если не договорится с пулом, он за такое забанит. Если произойдет сбой - я понесу вину за потерю пользователями больших денег. При мониторинге с телефонов (а теперь ясно что это работает и достаточно стабильно) каждый сможет включать эту функцию по желанию, и мониторить только нужные (проблемные) фермы. По поводу флага - метод RTC_WAKEUP вроде так и работает, будит телефон для выполнение задачи, но экран не включается. По крайней мере в варианте getService. У меня экран телефона всю ночь был выключен, запросы шли стабильно.
  3. Результаты ночного теста получились удивительными! AlarmManager отработал на ура (И кстати на HTC). Результаты можно посмотреть здесь http://kayfolom.ru/index.php?cmd=read&api_key=androidservicetest089 Правда есть некие странности, но думаю это проблемы моего кода. Некоторые вызовы удваиваются и утраиваются вот так (должно быть раз в 60 сек): 2017-02-26 01:28:43 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:27:43 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:26:43 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:26:11 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:25:11 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:24:11 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:24:11 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-26 01:24:11 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. Я читал что при некоторых флагах возможен экономичный вызов будильников - ближайшие по времени будильники вызываются в одно время, дабы не будить устройство лишний раз. Может тут как раз такой случай. Вот код сервиса: function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; begin SendRequest; Result:=TJService.JavaClass.START_NOT_STICKY; end; procedure TDM.SendRequest; Var Query : String; AMessage,AAPIKey : String; begin AAPIKey:='androidservicetest089'; AMessage:='AlarmManager в сервисе. Запрос раз в '+TimerInterval.ToString+' сек.'; Query:='http://kayfolom.ru/index.php?cmd=write&api_key='+AAPIKey+'&message='+AMessage; FHTTPThread:=THTTPThread.Create(Query); end; Поток с FreeOnTerminate:=True; Вроде все нормально...
  4. Попробовал AlarmManager. Интервал 30 секунд. Запускал сервис следующим образом: procedure TFormMain.InitServiceAlarmManager; var Intent: JIntent; PendingIntent: JPendingIntent; ATimerInterval : Integer; begin ATimerInterval:=30; Intent := TJIntent.Create; Intent.setClassName(TAndroidHelper.Context, StringToJString('com.embarcadero.services.ServiceTest090Service')); PendingIntent := TJPendingIntent.JavaClass.getService(TAndroidHelper.Context, 1, Intent, 0); TAndroidHelper.AlarmManager.&setRepeating(TJAlarmManager.JavaClass.RTC_WAKEUP, getTimeAfterInSecs(ATimerInterval), ATimerInterval * 1000, PendingIntent); end; procedure TFormMain.FormCreate(Sender: TObject); begin InitServiceAlarmManager; // FService:=TLocalServiceConnection.Create; // FService.StartService('ServiceTest090Service'); end; function TFormMain.getTimeAfterInSecs(Seconds: Integer): Int64; Var Calendar: JCalendar; begin Calendar := TJCalendar.JavaClass.getInstance; Calendar.add(TJCalendar.JavaClass.SECOND, Seconds); Result := Calendar.getTimeInMillis; end; end. Результат - та же хрень, вид сбоку: 2017-02-25 21:35:40 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:35:40 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:34:40 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:34:40 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:33:38 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:33:10 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:32:45 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:32:10 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:32:10 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:31:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:30:59 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. А тут я заблокировал телефон кнопкой и началось.... 2017-02-25 21:30:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:29:36 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:29:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:28:36 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:28:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:27:36 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:27:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:26:36 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:26:07 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:25:36 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. 2017-02-25 21:25:06 195.22.104.13 AlarmManager в сервисе. Запрос раз в 0 сек. Оставлю на ночь, посмотрим что будет....
  5. Andrey Efimov, огромное спасибо! Так и думал что глаз замылился и ответ перед глазами! Причем вашу статью раза четыре перечитал :-)
  6. Заработало? Оформить бы исправления как хелпер к THTTPClient, было бы замечательно. Хотя вроде в Берлине теперь нельзя так сделать?
  7. Спасибо за статью, все отлично работает. Вот только не допру как запустить не приложение, а сервис. Все темы в разделе Сервис перечитал, но информацию не нашел :-( Делаю по второму примеру: procedure TForm2.Button2Click(Sender: TObject); var Intent: JIntent; PendingIntent: JPendingIntent; begin // Создаём Интент Intent := TJIntent.Create; Intent.setClassName(TAndroidHelper.Context, StringToJString('com.embarcadero.firemonkey.FMXNativeActivity')); // Оборачиваем Интент в PendingIntent PendingIntent := TJPendingIntent.JavaClass.getActivity(TAndroidHelper.Context, 1, Intent, 0); // Устанавливаем оповещение TAndroidHelper.AlarmManager.&set(TJAlarmManager.JavaClass.RTC_WAKEUP, getTimeAfterInSecs(30), PendingIntent); end; Но activity "com.embarcadero.firemonkey.FMXNativeActivity" одинаковые у приложения и сервиса. Запускается именно приложение. Как сделать только запуск сервиса?
  8. Скорее всего глюки, посмотрите исходники, возможно найдете ошибку. Компонент NetHTTPClient "новый" и по традиции наполнен багами. Вот к примеру OnValidateServerCertificate разработчики сломали в XE8, а починили только в Берлине. Куки тоже были сломаны сознательно (скопипастили кусок кода не в то место, тремя строками ниже чем нужно), и чинились два апдейта, если не ошибаюсь. Еще одна традиция - исправление только одного бага в одном компоненте за один апдейт, так что проще будет исправить код самому.
  9. По моему опыту это разрешение не нужно. Включая вариант с установкой приложения на SD-карту. Разрешение требуется при использовании папок TPath.GetShared% или когда явно указано использование External Memory в http://docwiki.embarcadero.com/RADStudio/Seattle/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms P.S. Некоторые мои приложения опубликованные в маркете использует единственное разрешение Internet, при этом успешно пишут конфиги в GetHomePath. Проблем с установкой на SD-карту тоже не замечено. Сейчас гугль заставляет публиковать политику конфиденциальности при использовании разрешений, так что чем меньше разрешений, тем лучше. Да и пользователи с большим доверием относятся к приложению с минимальными разрешениями. Жаль что пуши требуют разрешение Идентификационные данные - пользователи постоянно обвиняют приложение в попытках украсть что то с их телефонов ;-)
  10. Провел небольшое исследование поведения таймера Posix в сервисе. Результаты не очень. Таймер ведет себя так же как и в приложении, главное отличие - не умирает окончательно, но рассчитывать на него не стоит. Перед экспериментом было отключено энергосбережение, экономия трафика во сне (телефон работал через wifi), т.е. созданы все условия для долгой и стабильной работы. 2017-02-24 23:22:51 - телефон ушел в сон. Таймер начал работать эпизодически, с провалами до получаса. 2017-02-25 07:24:58 - я проснулся и разблокировал телефон. Таймер опять нормально заработал. В следующей серии попробую протестировать сервис с AlarmManager, что то у меня подозрения что результаты будут не лучше. 2017-02-25 07:27:58 Posix-таймер в сервисе. Запрос раз в 60 сек. № 108 2017-02-25 07:26:58 Posix-таймер в сервисе. Запрос раз в 60 сек. № 107 2017-02-25 07:25:58 Posix-таймер в сервисе. Запрос раз в 60 сек. № 106 2017-02-25 07:24:58 Posix-таймер в сервисе. Запрос раз в 60 сек. № 105 2017-02-25 07:21:05 Posix-таймер в сервисе. Запрос раз в 60 сек. № 104 2017-02-25 07:14:00 Posix-таймер в сервисе. Запрос раз в 60 сек. № 103 2017-02-25 07:01:59 Posix-таймер в сервисе. Запрос раз в 60 сек. № 102 2017-02-25 06:46:33 Posix-таймер в сервисе. Запрос раз в 60 сек. № 101 2017-02-25 06:24:50 Posix-таймер в сервисе. Запрос раз в 60 сек. № 100 2017-02-25 06:13:58 Posix-таймер в сервисе. Запрос раз в 60 сек. № 99 2017-02-25 05:51:32 Posix-таймер в сервисе. Запрос раз в 60 сек. № 98 2017-02-25 05:30:07 Posix-таймер в сервисе. Запрос раз в 60 сек. № 97 2017-02-25 05:16:28 Posix-таймер в сервисе. Запрос раз в 60 сек. № 96 2017-02-25 05:07:28 Posix-таймер в сервисе. Запрос раз в 60 сек. № 95 2017-02-25 05:00:41 Posix-таймер в сервисе. Запрос раз в 60 сек. № 94 2017-02-25 04:41:01 Posix-таймер в сервисе. Запрос раз в 60 сек. № 93 2017-02-25 04:21:19 Posix-таймер в сервисе. Запрос раз в 60 сек. № 92 2017-02-25 04:00:40 Posix-таймер в сервисе. Запрос раз в 60 сек. № 91 2017-02-25 03:41:33 Posix-таймер в сервисе. Запрос раз в 60 сек. № 90 2017-02-25 03:16:59 Posix-таймер в сервисе. Запрос раз в 60 сек. № 89 2017-02-25 03:02:01 Posix-таймер в сервисе. Запрос раз в 60 сек. № 88 2017-02-25 02:44:54 Posix-таймер в сервисе. Запрос раз в 60 сек. № 87 2017-02-25 02:23:49 Posix-таймер в сервисе. Запрос раз в 60 сек. № 86 2017-02-25 02:10:28 Posix-таймер в сервисе. Запрос раз в 60 сек. № 85 2017-02-25 01:52:11 Posix-таймер в сервисе. Запрос раз в 60 сек. № 84 2017-02-25 01:32:57 Posix-таймер в сервисе. Запрос раз в 60 сек. № 83 2017-02-25 01:28:26 Posix-таймер в сервисе. Запрос раз в 60 сек. № 82 2017-02-25 01:27:26 Posix-таймер в сервисе. Запрос раз в 60 сек. № 81 2017-02-25 01:26:26 Posix-таймер в сервисе. Запрос раз в 60 сек. № 80 2017-02-25 01:25:27 Posix-таймер в сервисе. Запрос раз в 60 сек. № 79 2017-02-25 01:10:59 Posix-таймер в сервисе. Запрос раз в 60 сек. № 78 2017-02-25 01:00:27 Posix-таймер в сервисе. Запрос раз в 60 сек. № 77 2017-02-25 00:38:59 Posix-таймер в сервисе. Запрос раз в 60 сек. № 76 2017-02-25 00:19:22 Posix-таймер в сервисе. Запрос раз в 60 сек. № 75 2017-02-25 00:01:27 Posix-таймер в сервисе. Запрос раз в 60 сек. № 74 2017-02-24 23:51:15 Posix-таймер в сервисе. Запрос раз в 60 сек. № 73 2017-02-24 23:30:37 Posix-таймер в сервисе. Запрос раз в 60 сек. № 72 2017-02-24 23:22:51 Posix-таймер в сервисе. Запрос раз в 60 сек. № 71 2017-02-24 23:21:51 Posix-таймер в сервисе. Запрос раз в 60 сек. № 70 2017-02-24 23:20:51 Posix-таймер в сервисе. Запрос раз в 60 сек. № 69 2017-02-24 23:19:51 Posix-таймер в сервисе. Запрос раз в 60 сек. № 68 2017-02-24 23:18:51 Posix-таймер в сервисе. Запрос раз в 60 сек. № 67 2017-02-24 23:17:52 Posix-таймер в сервисе. Запрос раз в 60 сек. № 66 2017-02-24 23:16:52 Posix-таймер в сервисе. Запрос раз в 60 сек. № 65
  11. Спасибо огромное! Удаление папки C:\Users\%user%\.android\monitor-workspace действительно помогло. А 12 версий, это 12 папок с различными версиями java в "C:\Program Files\Java", и три десятка ярлыков типа '"C:\Program Files\Java\jre1.8.0_111\bin\javaw.exe" -jar "C:\Program Files (x86)\UTM5_Admin 5-2.1.005\UTM_Admin.jar"', ибо каждый jar на какой то версии глючит, на какой то пытается съесть 60 гигов оперативки и т.д. Вообще сложилось впечатление что программистов java принудительно держат на тяжелых наркотиках...
  12. Спасибо! Правда он не работает, тихо закрывается безо всяких сообщений. Вот нашел его логи, но мне они не о чем не говорят. Может кто подскажет в чем дело? !SESSION 2017-02-23 20:05:02.594 ----------------------------------------------- eclipse.buildId=unknown java.version=1.8.0_45 java.vendor=Oracle Corporation BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ru_RU Command-line arguments: -os win32 -ws win32 -arch x86_64 -data @noDefault !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:02.974 !MESSAGE Bundle reference:file:org.apache.ant_1.8.3.v201301120609/@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:02.981 !MESSAGE Bundle reference:file:org.apache.jasper.glassfish_2.2.2.v201205150955.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:02.985 !MESSAGE Bundle reference:file:org.apache.lucene.core_2.9.1.v201101211721.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.022 !MESSAGE Bundle reference:file:org.eclipse.help.base_3.6.101.v201302041200.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.025 !MESSAGE Bundle reference:file:org.eclipse.help.ui_3.5.201.v20130108-092756.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.028 !MESSAGE Bundle reference:file:org.eclipse.help.webapp_3.6.101.v20130116-182509.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.032 !MESSAGE Bundle reference:file:org.eclipse.jetty.server_8.1.3.v20120522.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.038 !MESSAGE Bundle reference:file:org.eclipse.platform.doc.user_4.2.2.v20130121-200410.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.042 !MESSAGE Bundle reference:file:org.eclipse.team.core_3.6.100.v20120524-0627.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.045 !MESSAGE Bundle reference:file:org.eclipse.team.ui_3.6.201.v20130125-135424.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.049 !MESSAGE Bundle reference:file:org.eclipse.ui.cheatsheets_3.4.200.v20120521-2344.jar@4 not found. !ENTRY org.eclipse.osgi 4 0 2017-02-23 20:05:03.054 !MESSAGE Bundle reference:file:org.eclipse.ui.intro_3.4.200.v20120521-2344.jar@4 not found. Update: похоже что батник пытается использовать не существующую и никогда не стоявшую на этом компе версию java.version=1.8.0_45 , упоминаний этой версии нет в реестре, нет на диске. откуда он может ее дергать? P.S. Ненавижу java, по основной работе имею дело с софтом написанным на этом убожестве, весь софт управления от Cisco, админки биллингов и прочая хрень на джаве, все работает не стабильно, танцы с бубнами, правки конфигов, после каждого обновления поиск причин почему половина софта перестала запускаться. UPDATE2: Может быть проблема из за того что на компе только 12 версий 64-битных java? Может этому чуду нужна 32-битная версия?
  13. Господа, просветите меня, где можно увидеть результат логов LOGI?
  14. Создал https://quality.embarcadero.com/browse/RSP-16910 по этой проблеме. Надеюсь разработчики что то подскажут.
  15. Создал https://quality.embarcadero.com/browse/RSP-16910 . Правда мой английский не позволяет свободно описать проблему, надеюсь переводчик гугл справился с задачей более-менее сносно :-)
  16. Вот именно то что я искал, спасибо! Хорошая статья, теперь в голове все встало на свои места.
  17. К сожалению на чистом проекте воспроизвести глюк не удалось, а в том проекте где глюк наблюдался, сделал все ручками c помощью TObjectList<TImage>...
  18. TDictionary работает посредством хеш таблицы, и работает чертовски быстро (исключая некоторые специфичные моменты Collision resolution). А код просто выдрал из живого проекта, поэтому лишнее присутствует ;-)
  19. А как решить проблему на андроид ТВ-приставках (тема уже дважды поднималась на форуме, но решения нет) - приложения Дельфи не реагируют на нажатие кнопки Ок с пульта управления (Инфракрасный пульт), на цифро-буквенные, меню, назад реагируют нормально. Товарищ по моей просьбе написал приложение на андроид студии, форма с кнопкой (фокус на кнопке), при нажатии выводится сообщение "Кнопка нажата" - на тв-приставки с пульта кнопка прекрасно нажимается. Аналогичное приложение на Дельфи (Berlin Update 2) никак не реагирует. Из за этой проблемы путь на тв-приставки приложениям на Дельфи закрыт :-(
  20. Если именно как на приведенной вами картинке то вот так: Делаете ListView с DynamicAppearance, включаете DesingMode, добавляете необходимые поля, включая TListItemAccessory с AccessoryType=Checkmark (он и будет отображать красивые галочки). Не забудьте дать названия добавленным элементам. В моем коде TListItemAccessory называется "ShowPool" P.S. Вариант, предложенный выше, с ListView1.EditMode := True будет выглядеть страшненько, чекбоксы не очень хорошо смотрятся в интерфейсе приложений. procedure TFormMain.FillSettingPools; Var I : Integer; AItem : TListViewItem; begin ListViewPools.BeginUpdate; ListViewPools.Items.Clear; for I := 0 to FPoolList.Count-1 do begin AItem:=ListViewPools.Items.Add; AItem.Data['CoinName']:=FPoolList.Items[I].CoinName; AItem.Data['CoinDetail']:=FPoolList.Items[I].Href; AItem.Data['ShowPool']:=FPoolList.Items[I].ShowPool; TListItemAccessory(AItem.View.FindDrawable('ShowPool')).Visible:=FPoolList.Items[I].ShowPool; //Boolean end; ListViewPools.EndUpdate; end; procedure TFormMain.ListViewPoolsUpdateObjects(const Sender: TObject; const AItem: TListViewItem); Var AItemAccessory : TListItemAccessory; begin AItemAccessory:=TListItemAccessory(AItem.View.FindDrawable('ShowPool')); if AItem.Data['ShowPool'].AsBoolean then AItemAccessory.Visible:=True Else AItemAccessory.Visible:=False; end; procedure TFormMain.ListViewPoolsItemClick(const Sender: TObject; const AItem: TListViewItem); Var I : Integer; S : String; AListItemAccessory : TListItemAccessory; APool : TPool; AShowPool : Boolean; begin AListItemAccessory:=TListItemAccessory(AItem.View.FindDrawable('ShowPool')); if AListItemAccessory<>nil then begin AShowPool:=AItem.Data['ShowPool'].AsBoolean; AShowPool:=Not AShowPool; AListItemAccessory.Visible:=AShowPool; AItem.Data['ShowPool']:=AShowPool; S:=AItem.Data['CoinName'].AsString; for I := 0 to FPoolList.Count-1 do begin If FPoolList.Items[I].CoinName.Equals(S) Then begin APool:=FPoolList.Items[I]; APool.ShowPool:=AShowPool; FPoolList.Items[I]:=APool; Break; end; end; end; FillListViewPoolsMaster; SavePools; end;
  21. Вот бы статью с иллюстрациями о правильном использовании TImageList. Интерфейс дизайн-части крайне нелогичный и запутанный. Мой опыт использования обычно заканчивается психозом из за того что компонент рушит приложение из за ошибок с индексами. И фиг поймешь почему он падает при попытке обращения к некоему индексу 3 (где то в недрах своего кода), если в нем всего две картинки, которые используются на двух кнопках.
  22. Для этого лучше использовать TCPServer и TCPClient, протокол TCP сделает это все гораздо лучше, чем велосипед на UDP. Но если именно UDP, то алгоритм такой: нумеруете все отправляемые пакеты, вставляя в тело пакета его номер, что бы на стороне приемника контролировать все ли пакеты пришли и в правильной ли последовательности (udp пакеты могут прийти не в той последовательности в которой отправлены), в завершении передачи отправляете хэш файла (md5 к примеру) для контроля целостности всего файла. Естественно при не получении какого то пакета, нужно отправлять запрос на сервер о повторной отправке. Желательно еще и хэш каждого пакета к нему присобачивать. Так же нужно учесть обрезку и дробление пакетов из за разных размеров MTU на промежуточных устройствах сети.
  23. Попробуйте на событие OnMouseDown делать ListBox1.HitTest:=False, а на OnMouseUp ListBox1.HitTest:=True
×
×
  • Создать...