Android gstack命令,android-TIdIOHandler.Write过程无法在移动设备上运行

我正在尝试将流从移动设备(iOS,Android)发送到TCP Server.对于服务器和客户端,我正在使用Indy组件.

当我尝试从移动设备中运行的FMX应用程序发送流时​​,会发生此问题.如果我从Windows运行客户端代码,则客户端会将流发送到Server App.但是我从移动设备上运行了相同的代码,但未发送流.

这是服务器和客户端的最小,完整和可验证的示例,可以重现此问题.

服务器端 .该服务器是VCL应用程序.

unit uServer;

interface

uses

Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,

Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent,

IdCustomTCPServer, IdTCPServer, Vcl.StdCtrls, IdContext;

type

TFrmServer = class(TForm)

IdTCPServer1: TIdTCPServer;

MemoLog: TMemo;

procedure FormCreate(Sender: TObject);

procedure IdTCPServer1Execute(AContext: TIdContext);

private

{ Private declarations }

public

{ Public declarations }

end;

var

FrmServer: TFrmServer;

implementation

uses

IdGlobal,

IdIOHandler,

System.StrUtils;

{$R *.dfm}

procedure TFrmServer.FormCreate(Sender: TObject);

begin

IdTCPServer1.Bindings.Clear;

IdTCPServer1.DefaultPort := 28888;

IdTCPServer1.Active := True;

MemoLog.Lines.Add('Running');

end;

procedure TFrmServer.IdTCPServer1Execute(AContext: TIdContext);

var

LHandler : TIdIOHandler;

s: string;

LMemoryStream : TMemoryStream;

AFormatSettings: TFormatSettings;

d : Int64;

begin

try

LHandler := AContext.Connection.IOHandler;

s := LHandler.ReadLn(LF, IdTimeoutDefault, MaxInt);

AFormatSettings := TFormatSettings.Create;

if (s <> '') then

begin

if StartsText('', s) then

begin

TThread.Queue(nil,

procedure

begin

MemoLog.Lines.Add(Format('%s', [s], AFormatSettings));

end

);

LMemoryStream := TMemoryStream.Create;

try

LHandler.LargeStream := True;

LHandler.ReadStream(LMemoryStream, -1, False);

d := LMemoryStream.Size;

TThread.Queue(nil,

procedure

begin

MemoLog.Lines.Add(Format('Stream Size %d', [d], AFormatSettings));

end

);

finally

LMemoryStream.Free;

end;

end

else

LHandler.InputBuffer.Clear;

end;

except

on E: Exception do

begin

s := E.Message;

TThread.Queue(nil,

procedure

begin

MemoLog.Lines.Add(Format('Exception %s', [s], AFormatSettings));

end

);

end;

end;

end;

end.

客户端(FMX应用程序)

unit uClient;

interface

uses

System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,

FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,

IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, FMX.ScrollBox,

FMX.Memo, FMX.Controls.Presentation, FMX.StdCtrls;

type

TFrmClient = class(TForm)

IdTCPClient1: TIdTCPClient;

Button1: TButton;

MemoLog: TMemo;

procedure FormCreate(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

procedure Send;

public

{ Public declarations }

end;

var

FrmClient: TFrmClient;

implementation

{$R *.fmx}

type

TSendThread = class(TThread)

private

FTCPClient : TIdTCPClient;

public

procedure Execute; override;

constructor Create(ATCPClient : TIdTCPClient); reintroduce;

end;

procedure TFrmClient.Button1Click(Sender: TObject);

begin

Send;

end;

procedure TFrmClient.FormCreate(Sender: TObject);

begin

try

IdTCPClient1.Port := 28888;

IdTCPClient1.Host := '192.168.1.134'; //change this to the ip of the TCP server.

IdTCPClient1.ConnectTimeout := 5000;

IdTCPClient1.Connect();

MemoLog.Lines.Add('Connected');

except on E: Exception do

MemoLog.Lines.Add('Exception ' + E.Message);

end;

end;

procedure TFrmClient.Send;

begin

if IdTCPClient1.Connected then

TSendThread.Create(IdTCPClient1);

end;

{ TSendThread }

constructor TSendThread.Create(ATCPClient: TIdTCPClient);

begin

inherited Create(False);

FTCPClient := ATCPClient;

end;

procedure TSendThread.Execute;

var

LStream : TStream;

d : Int64;

begin

LStream := TMemoryStream.Create;

try

//Send a text from all the platforms works perfect.

FTCPClient.IOHandler.WriteLn('');

LStream.Size := 1024;

LStream.Position := 0;

d := LStream.Size;

FTCPClient.IOHandler.LargeStream := True;

//this only works from Windows

FTCPClient.IOHandler.Write(LStream, d, True);

finally

LStream.Free;

end;

end;

end.

问题是,如何使用Indy组件从移动设备发送流?

更新:

Android权限

解决方法:

最终,我发现了这个问题,我误以为没有发送数据,发送了流,但是服务器无法处理流,因为TIdIOHandler.ReadStream函数无法正确读取流的大小.在AByteCount参数中传递-1值时,会发生这种情况.然后,使用TIdIOHandler.ReadInt64或TIdIOHandler.ReadInt32函数读取流的大小,并且在内部,这些函数试图使用GStack.NetworkToHost函数转换整数的字节序.

我解决了读取流大小而不转换字节序的问题.

我替换了这条线

LHandler.ReadStream(LMemoryStream, -1, False);

对于此代码

LHandler.LargeStream := True;

LHandler.ReadBytes(LBytes, SizeOf(Int64), False);

d := BytesToInt64(LBytes);

LHandler.ReadStream(LMemoryStream, d, False);

标签:delphi-10-1-berlin,ios,android,delphi

来源: https://codeday.me/bug/20191112/2023937.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值