Win32 / Android的基本Indy TCP客户端/服务器

时间:2013-12-10 22:23:42

标签: android tcp indy firemonkey delphi-xe5

我正在尝试设置一个非常基本的单个客户端/服务器系统,因此我可以从我的PC发送一个字符串到Android平板电脑。平板电脑对字符串执行某些操作,然后将字符串发送回PC。代码:

服务器端(平板电脑)

procedure TForm1.Button1Click(Sender: TObject); // start the server
begin
  IdTCPServer1.Bindings.Clear;
  IdTCPServer1.Bindings.Add.SetBinding('xxx.xxx.x.x', 4405); // for the xxx's the IP adres of the tablet 
  IdTCPServer1.Active := True;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var s:string;
begin
  s := AContext.Connection.IOHandler.ReadLn(); 
  Try
    ... do something with the string
    AContext.Connection.IOHandler.Writeln('ready');
  Except
    AContext.Connection.IOHandler.Writeln('Error');
  End;
  AContext.Connection.Disconnect;
end;

客户端:(桌面)

procedure TFMain.FormCreate(Sender: TObject);
begin
  IdTCPClient1.host := 'xxx.xxx.x.x';  // xxx's the IP address of the tablet
  IdTCPClient1.Port := 4405;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin
  s := 'some string';
  IdTCPClient1.Connect;
  IdTCPClient1.IOHandler.Writeln(s);
  if IdTCPClient1.IOHandler.ReadLn='ready' then Button1.text := 'ready'
                                           else Button1.text := 'failed';

  IdTCPClient1.Disconnect;
end;

在本地主机或家庭网络中的两台不同PC上运行时,程序运行正常。但是,在平板电脑上安装服务器端时,单击桌面上的button1将导致“连接正常关闭”。这真的很令人沮丧,因为它在两台PC上运行正常,但在PC机上没有安卓平板电脑。我在互联网上搜索了很长时间,也许它与字符串结尾的差异有关,或者(XE5的实现)Android中的线程可能也存在问题。任何有关如何运行上述代码或以不同方式(通过IP)使用XE5在PC和平板电脑之间进行通信的帮助都非常受欢迎。

杰拉德

稍后添加: 通过wireshark,我试图查看正在发送的信息。当在两个表现正常的桌面之间运行时,我得到的通信我假设以下内容适用于手头的程序(server = 192.168.2.11,client = 192.168.2.10)。

197 9.209090000 192.168.2.10    192.168.2.11    TCP 66  56699 > ds-admin [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
198 9.212694000 192.168.2.11    192.168.2.10    TCP 66  ds-admin > 56699 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
199 9.212764000 192.168.2.10    192.168.2.11    TCP 54  56699 > ds-admin [ACK] Seq=1 Ack=1 Win=65536 Len=0
200 9.213041000 192.168.2.10    192.168.2.11    TCP 111 56699 > ds-admin [PSH, ACK] Seq=1 Ack=1 Win=65536 Len=57
201 9.217302000 192.168.2.11    192.168.2.10    TCP 119 ds-admin > 56699 [PSH, ACK] Seq=1 Ack=58 Win=65536 Len=65
202 9.217304000 192.168.2.11    192.168.2.10    TCP 60  ds-admin > 56699 [FIN, ACK] Seq=66 Ack=58 Win=65536 Len=0
203 9.217349000 192.168.2.10    192.168.2.11    TCP 54  56699 > ds-admin [ACK] Seq=58 Ack=67 Win=65536 Len=0
204 9.217543000 192.168.2.10    192.168.2.11    TCP 54  56699 > ds-admin [FIN, ACK] Seq=58 Ack=67 Win=65536 Len=0
207 9.225011000 192.168.2.11    192.168.2.10    TCP 60  ds-admin > 56699 [ACK] Seq=67 Ack=59 Win=65536 Len=0

另一方面,当使用Android平板电脑作为服务器做同样的事情时,我得到以下内容(服务器= 192.168.2.8,客户端= 192.168.2.10):

116 4.792467000 192.168.2.10    192.168.2.8 TCP 66  56407 > ds-admin [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
117 4.802487000 192.168.2.8 192.168.2.10    TCP 66  ds-admin > 56407 [SYN, ACK] Seq=0 Ack=1 Win=14600 Len=0 MSS=1460 SACK_PERM=1 WS=64
118 4.802571000 192.168.2.10    192.168.2.8 TCP 54  56407 > ds-admin [ACK] Seq=1 Ack=1 Win=65536 Len=0
119 4.802857000 192.168.2.10    192.168.2.8 TCP 111 56407 > ds-admin [PSH, ACK] Seq=1 Ack=1 Win=65536 Len=57
120 4.808816000 192.168.2.8 192.168.2.10    TCP 60  ds-admin > 56407 [FIN, ACK] Seq=1 Ack=1 Win=14656 Len=0
121 4.808860000 192.168.2.10    192.168.2.8 TCP 54  56407 > ds-admin [ACK] Seq=58 Ack=2 Win=65536 Len=0
122 4.808944000 192.168.2.10    192.168.2.8 TCP 54  56407 > ds-admin [FIN, ACK] Seq=58 Ack=2 Win=65536 Len=0
123 4.812517000 192.168.2.8 192.168.2.10    TCP 60  ds-admin > 56407 [ACK] Seq=2 Ack=58 Win=14656 Len=0
124 4.813608000 192.168.2.8 192.168.2.10    TCP 60  ds-admin > 56407 [RST, ACK] Seq=2 Ack=58 Win=14656 Len=0
125 4.813609000 192.168.2.8 192.168.2.10    TCP 60  ds-admin > 56407 [RST] Seq=2 Win=0 Len=0
126 4.814570000 192.168.2.8 192.168.2.10    TCP 60  ds-admin > 56407 [RST] Seq=2 Win=0 Len=0

这是我第一次看到这种信息,但似乎在工作桌面 - 桌面情况下,行200对应于客户端命令IdTCPClient1.IOHandler.Writeln(s),而行201对应于服务器命令AContext .Connection.IOHandler.Writeln(...)。在桌面平板电脑配置中,客户端将字符串发送到服务器(第119行),但没有[PSH,ACK]返回。相反,有一个[FIN,ACK]响应。这似乎表明Android中的服务器端语句出了问题:s:= AContext.Connection.IOHandler.ReadLn();任何想法可能是什么以及如何解决它?

稍后再添加:在该行周围添加try / except语句 s:= AContext.Connection.IOHandler.ReadLn(); 然后引发异常“连接正常关闭”的异常。当调试delphi说:Project test.apk引发异常类分段错误(11)并转到单元IdIOHandler rev 1.123(2/8/05)中的以下函数。

function TIdIOHandler.ReadLn(AByteEncoding: IIdTextEncoding = nil
  {$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF}
  ): string;
{$IFDEF USE_CLASSINLINE}inline;{$ENDIF}
begin
  Result := ReadLn(LF, IdTimeoutDefault, -1, AByteEncoding
    {$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF}
    );
end;

那一刻的召唤堆是(第一个项目前面有一个箭头,剩下一个蓝色的子弹,除了最后3个项目,前面有一个灰色的子弹):

Idiohandler.TIdIOHandler.ReadLn(0x797e8cb4,nil,nil)
Umaintablet.TFCalibration_tablet_side.IdTCPServer1Execute(0x74124e70,0x769d76a0)
Idcustomtcpserver.TIdCustomTCPServer.DoExecute(0x76414480,0x769d76a0)
Idcontext.TIdContext.Run(0x769d76a0)
Idtask.TIdTask.DoRun(0x769d76a0)
Idthread.TIdThreadWithTask.Run(0x766bd258)
Idthread.TIdThread.Execute(0x766bd258)
System.Classes.ThreadProc(0x766bd258)
System.ThreadWrapper(0x766bd300)
:4003F3DC __thread_entry
:4003EAC8 pthread_create
:00000000 ??

1 个答案:

答案 0 :(得分:0)

对于只需要单个客户端的特定问题,TidSimpleServer对象而不是TidTCPserver对象在我的Android上可以正常工作。