Delphi-使用Indy检查客户端状态的简单TCP客户端/服务器

盖刷

我最近开始使用Indy 10(来自Delphi XE3)和TCP连接。现在,我正在尝试创建一个简单的服务器应用程序以检查客户端状态。但是,当我尝试在已连接某些客户端的情况下停用TCPServer时,客户端确实会断开连接,但TCPServer会停止应答。

我读过某个地方,TCPServer应该可以毫无问题地处理客户端的断开连接。我必须在OnExecute事件上添加一些代码来解决此问题吗?

这是代码:

procedure TfrmMain.btnConnectClick(Sender: TObject);
begin
  If (not TCPServer.Active) Then
  Try
    TCPServer.Bindings.Clear;
    With TCPServer.Bindings.Add Do
    Begin
      IP := '192.168.1.11';
      Port := StrToInt(edtPort.Text);
    end;
    TCPServer.Active := True;
  Except
    On E:Exception Do ShowMessage(E.Message);
  End
end;

procedure TfrmMain.btnDisconnectClick(Sender: TObject);
begin
  If (TCPServer.Active) Then
  Try
    TCPServer.Active := False;
  Except
    On E:Exception Do ShowMessage(E.Message);
  End
end;

procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
var
  IdStackWin: TIdStackWindows;
begin
  IdStackWin := TIdStackWindows.Create;
  With IdStackWin Do
  Try
    memLog.Lines.Add('Connected - ' + HostByAddress(AContext.Binding.PeerIP) + ' (' + AContext.Binding.PeerIP + ')');
  Finally
    IdStackWin.Free;
  end;
end;


procedure TfrmMain.TCPServerDisconnect(AContext: TIdContext);
var
  IdStackWin: TIdStackWindows;
begin
  IdStackWin := TIdStackWindows.Create;
  With IdStackWin Do
  Try
    memLog.Lines.Add('Disconnected - ' + HostByAddress(AContext.Binding.PeerIP) + ' (' + AContext.Binding.PeerIP + ')');
  Finally
    IdStackWin.Free;
  end;
end;

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
begin
   Application.ProcessMessages;
end;

谢谢!

雷米·勒博

您正在犯一些错误。

  1. 不要TIdStack直接实例化一个类。当任何Indy套接字组件都处于活动状态时,Indy会为您实例化一个实例。如果需要访问套接字堆栈,请使用全局GStack对象指针,例如:

    GStack.HostByAddress(AContext.Binding.PeerIP)
    

    在极少数情况下,GStack当没有Indy组件处于活动状态时需要访问时,可以使用TIdStack.IncUsage()TIdStack.DecUsage()方法调用包装代码,以确保GStack可用。

  2. TIdTCPServer是一个多线程组件。侦听套接字和客户端套接字在工作线程中运行。OnConnectOnDisconnectOnExecuteOnException,和OnListenException事件在这些工作线程的情况下解雇,而不是在主UI线程的上下文。因此,您必须与主线程进行同步,以便安全地访问VCL / FMX UI控件,否则会发生不良情况,包括死锁等。您可以在需要时使用Indy的TIdSync(同步)或TIdNotify类(异步)类,或TThread.Synchronize()(同步)或TThread.Queue()(异步)方法的静态版本与主线程同步。或您选择的任何其他线程间同步机制。VCL / FMX UI控件必须仅在主线程的上下文中访问。

    警告:TIdTCPServer从主线程取消激活时,请勿使用同步同步,这是有保证的死锁。使用异步同步,或从另一个线程(尽管不是服务器线程)停用服务器,以便主线程可以自由地正常处理同步。

  3. Application.ProcessMessages()切勿在主UI线程之外调用它。无需从TIdTCPServer事件中调用它

尝试以下方法:

procedure TfrmMain.btnConnectClick(Sender: TObject);
begin
  if not TCPServer.Active then
  begin
    TCPServer.Bindings.Clear;
    with TCPServer.Bindings.Add do
    Begin
      IP := '192.168.1.11';
      Port := StrToInt(edtPort.Text);
    end;
    TCPServer.Active := True;
  end;
end;

procedure TfrmMain.btnDisconnectClick(Sender: TObject);
begin
  TCPServer.Active := False;
end;

procedure TfrmMain.TCPServerConnect(AContext: TIdContext);
var
  Msg: string;
begin
  Msg := 'Connected - ' + GStack.HostByAddress(AContext.Binding.PeerIP) + ' (' + AContext.Binding.PeerIP + ')';
  TThread.Queue(nil,
    procedure
    begin
      memLog.Lines.Add(Msg);
    end
  );
end;

procedure TfrmMain.TCPServerDisconnect(AContext: TIdContext);
var
  Msg: string;
begin
  Msg := 'Disconnected - ' + GStack.HostByAddress(AContext.Binding.PeerIP) + ' (' + AContext.Binding.PeerIP + ')';
  TThread.Queue(nil,
    procedure
    begin
      memLog.Lines.Add(Msg);
    end
  );
end;

procedure TfrmMain.TCPServerExecute(AContext: TIdContext);
begin
  // your communications logic here
end;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Delphi-使用Indy检查客户端状态的简单TCP客户端/服务器

来自分类Dev

delphi indy udp客户端和服务器音频聊天

来自分类Dev

如何使Indy服务器和客户端在C ++中的单独线程上侦听数据而不是在Delphi中

来自分类Dev

Delphi EMS FireDAC:如何使用EMS将参数从客户端传递到服务器?

来自分类Dev

Delphi EMS FireDAC:如何使用EMS将参数从客户端传递到服务器?

来自分类Dev

Delphi NT 服务作为客户端(不是服务器),OnExecute 与 OnStart

来自分类Dev

从Delphi客户端将JSON数据发布到RESTful Datasnap服务器

来自分类Dev

Delphi-Indy TCPServer如何管理客户端连接?

来自分类Dev

如何解决Delphi 2007服务器与RAD XE7客户端之间的Indy套接字错误#111连接被拒绝?

来自分类Dev

如何解决Indy套接字错误#111,Delphi 2007服务器与RAD XE7客户端之间的连接被拒绝?

来自分类Dev

用于Delphi的WebSocket客户端实现

来自分类Dev

如何在Delphi中使用HTTP客户端API

来自分类Dev

运行像其一样的Delphi客户端已连接到Web服务器-没有Web服务器。是否有可能?

来自分类Dev

DELPHI“调用的对象已与其客户端断开连接”

来自分类Dev

更改Delphi WSDL客户端定义以支持不同的WDSLVersions

来自分类Dev

使用g ++的TCP服务器客户端

来自分类Dev

如何在Delphi xe中使用HTTP客户端登录网站

来自分类Dev

让TCP客户端搜索TCP服务器

来自分类Dev

让TCP客户端搜索TCP服务器

来自分类Dev

Delphi SOAP 客户端 Windows 身份验证自 Delphi 10.3 起已损坏

来自分类Dev

Java简单服务器客户端程序

来自分类Dev

套接字编程-简单的客户端/服务器

来自分类Dev

使用C#的TCP / IP服务器/客户端多连接并接收客户端的公共IP地址

来自分类Dev

监督gen_tcp客户端/服务器

来自分类Dev

TCP客户端-服务器程序的问题

来自分类Dev

XmlSerializer和NetworkStream与Tcp服务器-客户端

来自分类Dev

TCP服务器和客户端Java

来自分类Dev

c#从服务器ping TCP客户端

来自分类Dev

TCP / IP服务器客户端

Related 相关文章

  1. 1

    Delphi-使用Indy检查客户端状态的简单TCP客户端/服务器

  2. 2

    delphi indy udp客户端和服务器音频聊天

  3. 3

    如何使Indy服务器和客户端在C ++中的单独线程上侦听数据而不是在Delphi中

  4. 4

    Delphi EMS FireDAC:如何使用EMS将参数从客户端传递到服务器?

  5. 5

    Delphi EMS FireDAC:如何使用EMS将参数从客户端传递到服务器?

  6. 6

    Delphi NT 服务作为客户端(不是服务器),OnExecute 与 OnStart

  7. 7

    从Delphi客户端将JSON数据发布到RESTful Datasnap服务器

  8. 8

    Delphi-Indy TCPServer如何管理客户端连接?

  9. 9

    如何解决Delphi 2007服务器与RAD XE7客户端之间的Indy套接字错误#111连接被拒绝?

  10. 10

    如何解决Indy套接字错误#111,Delphi 2007服务器与RAD XE7客户端之间的连接被拒绝?

  11. 11

    用于Delphi的WebSocket客户端实现

  12. 12

    如何在Delphi中使用HTTP客户端API

  13. 13

    运行像其一样的Delphi客户端已连接到Web服务器-没有Web服务器。是否有可能?

  14. 14

    DELPHI“调用的对象已与其客户端断开连接”

  15. 15

    更改Delphi WSDL客户端定义以支持不同的WDSLVersions

  16. 16

    使用g ++的TCP服务器客户端

  17. 17

    如何在Delphi xe中使用HTTP客户端登录网站

  18. 18

    让TCP客户端搜索TCP服务器

  19. 19

    让TCP客户端搜索TCP服务器

  20. 20

    Delphi SOAP 客户端 Windows 身份验证自 Delphi 10.3 起已损坏

  21. 21

    Java简单服务器客户端程序

  22. 22

    套接字编程-简单的客户端/服务器

  23. 23

    使用C#的TCP / IP服务器/客户端多连接并接收客户端的公共IP地址

  24. 24

    监督gen_tcp客户端/服务器

  25. 25

    TCP客户端-服务器程序的问题

  26. 26

    XmlSerializer和NetworkStream与Tcp服务器-客户端

  27. 27

    TCP服务器和客户端Java

  28. 28

    c#从服务器ping TCP客户端

  29. 29

    TCP / IP服务器客户端

热门标签

归档