При работе с Android-приложением, использующим Indy's TIdTcpClient и TIdThreadComponent, пользователь столкнулся с проблемой подключения и смены IP-адреса. После того, как было проверено, что tanto Delphi's bundled и последняя версия Indy работают без проблем при чтении и записи, но при смене IP-адреса приложение часто замораживалось, а иногда и вовсе переставало отвечать.
Ремей Лейбоу предложил альтернативное решение, которое включает в себя перемещение логики подключения в поток чтения, где поток соединяется, читает, пока не закончит, и затем отключается, повторяя этот процесс до тех пор, пока не будет остановлен. Если IP-адрес должен быть изменен, новый IP-адрес кэшируется, и поток просит его подключиться при первой возможности. Таким образом, поток сам решает, когда безопасно читать и когда безопасно отключаться и подключаться, уведомляя главный поток о любых изменениях состояния по мере необходимости.
Код на Object Pascal (Delphi) для решения проблемы:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBase, IdGlobal, IdTCP, IdTCPClient, IdThread;
type
TForm1 = class(TForm)
IdTCPClient1: TIdTCPClient;
IdThreadComponent1: TIdThreadComponent;
procedure IdThreadComponent1Execute(Sender: TObject);
procedure IdTCPClient1Connect(Sender: TObject);
procedure IdTCPClient1Disconnect(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
ServerHost: string;
ServerHostChanged: Boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.IdThreadComponent1Execute(Sender: TObject);
begin
if (IdTCPClient1.Host = '') or ServerHostChanged then
begin
IdTCPClient1.Host := ServerHost;
ServerHostChanged := False;
end;
try
IdTCPClient1.Connect;
except
on E: Exception do
begin
// Обработка ошибки подключения
Exit;
end;
end;
try
// Читать сообщения и обрабатывать их по мере необходимости
while IdThreadComponent1.Active and (not ServerHostChanged) do
begin
try
if IdTCPClient1.IOHandler.InputBufferIsEmpty then
begin
IdTCPClient1.IOHandler.CheckForDataOnSource(250);
IdTCPClient1.IOHandler.CheckForDisconnect;
if IdTCPClient1.IOHandler.InputBufferIsEmpty then Continue;
end;
// Читать сообщение и обработать его
except
// Обработка ошибки чтения
Break;
end;
end;
finally
IdTCPClient1.Disconnect;
end;
end;
procedure TForm1.IdTCPClient1Connect(Sender: TObject);
begin
// Обработка успешного подключения
end;
procedure TForm1.IdTCPClient1Disconnect(Sender: TObject);
begin
// Обработка отключения
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdThreadComponent1.OnExecute := IdThreadComponent1Execute;
// Запустить поток, когда вы готовы к первому подключению
IdThreadComponent1.Start;
end;
end.
Чтобы проверить, доступен ли данный IP-адрес, пользователь может попробовать просто отправить пакет ICMP (ping) на каждый IP-адрес, чтобы увидеть, находится ли он в сети. Однако это не гарантирует, что TCP-сервер может быть подключен. Если у пользователя есть доступ к коду устройства, он может добавить UDP-сервер, который работает рядом с TCP-сервером, и затем отправить UDP-广播到网络子网,查看哪些UDP服务器响应。
Таким образом, пользователь может решить проблему подключения в Android-приложении с помощью Indy и Delphi, следуя предложенному альтернативному решению и используя правильный способ проверки доступности IP-адресов.
При решении проблемы подключения в Android-приложении с использованием Indy и Delphi была предложена стратегия перемещения логики подключения в поток чтения, который управляет процессами соединения, чтения, отключения и переподключения при изменении IP-ад
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.