Indy 10 TCP客户端服务器 - 测试开放通信渠道

3
我正在修改一个Indy10 TCP/IP应用程序,希望能够得到您在客户端实现以下功能的建议、意见和示例代码:
a) 应用程序启动时显示闪屏,验证客户端计算机是否有Internet访问权限以及TCP服务器是否正在运行并等待通信。如果不是这种情况,则应用程序应该终止。
b) 在客户端与服务器之间进行任何数据交换之前执行(a)。
此外,服务器需要定期广播某种消息来通知可能的客户机它正在运行吗?
感谢您的帮助。

我对 b) 有点迷惑。你是不是指在发送命令之前需要检查连接? - TLama
2个回答

2
如何验证是否可以连接到TCP服务器?
对于您的第一个问题:一定要将连接尝试包装到一个单独的线程中,并在启动闪屏界面时运行该线程。在该线程中,您可以简单地尝试使用Connect并捕获异常。如果引发异常,则连接失败。如果没有,您就能够连接了。关于此状态的通知,我会使用自定义消息,将其发送到闪屏界面表单中,如下伪代码所示:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdTCPClient;

const
  WM_CONNECTION_NOTIFY = WM_USER + 1;
  SC_CONNECTION_FAILURE = 0;
  SC_CONNECTION_SUCCESS = 1;

type
  TConnThread = class(TThread)
  private
    FMsgHandler: HWND;
    FTCPClient: TIdTCPClient;
  protected
    procedure Execute; override;
  public
    constructor Create(const AHost: string; APort: Word; ATimeout: Integer;
      AMsgHandler: HWND); reintroduce;
    destructor Destroy; override;
  end;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FConnThread: TConnThread;
    procedure WMConnectionNotify(var AMessage: TMessage); message WM_CONNECTION_NOTIFY;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TConnThread }

constructor TConnThread.Create(const AHost: string; APort: Word;
  ATimeout: Integer; AMsgHandler: HWND);
begin
  inherited Create(False);
  FreeOnTerminate := False;
  FMsgHandler := AMsgHandler;
  FTCPClient := TIdTCPClient.Create(nil);
  FTCPClient.Host := AHost;
  FTCPClient.Port := APort;
  FTCPClient.ConnectTimeout := ATimeout;
end;

destructor TConnThread.Destroy;
begin
  FTCPClient.Free;
  inherited;
end;

procedure TConnThread.Execute;
begin
  try
    FTCPClient.Connect;
    PostMessage(FMsgHandler, WM_CONNECTION_NOTIFY, 0, SC_CONNECTION_SUCCESS);
  except
    PostMessage(FMsgHandler, WM_CONNECTION_NOTIFY, 0, SC_CONNECTION_FAILURE);
  end;
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FConnThread := TConnThread.Create('123.4.5.6', 123, 5000, Handle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FConnThread.Free;
end;

procedure TForm1.WMConnectionNotify(var AMessage: TMessage);
begin
  case AMessage.LParam of
    // the connection failed
    SC_CONNECTION_FAILURE: ;
    // the connection succeeded
    SC_CONNECTION_SUCCESS: ;
  end;
end;

end.

服务器需要重复广播某种消息来通知潜在客户端它正在运行吗?

不需要,这是一个不同的方向 - 客户端询问服务器是否正在运行。这是因为服务器不知道客户端,但客户端知道服务器。


2
关于“服务器是否需要重复广播某种消息”的问题:
有些系统(服务器、服务)会使用IP组播主动向感兴趣的客户端广告其位置(IP地址、端口号),甚至附加一些其他信息(例如状态)。
使用Internet Direct(Indy)UDP组件,可以很容易地在服务器和客户端两端实现。
下面是一个Delphi的IP组播示例,用于开源消息代理Apache ActiveMQ,并提供了完整的源代码: 使用Delphi XE4和Indy 10.6发现ActiveMQ代理

我们在哪里可以下载这个珍宝? - NaN
@EASI 谢谢夸奖 :) 完整的应用程序代码已经包含在文章中(我已更新链接以指向与 XE4 兼容的 Indy 10.6 版本)。 - mjn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接