3

I am modifying an Indy10 TCP/IP application and I would like your suggestions/opinions/sample code on implementing a client side function that does the following

a) on application startup when the splash screen is displayed, it verifies that the client computer has internet access and the TCP Server is up and running and waiting for communication. If this is not the case, the application should terminate.

b) does (a) above before ANY data exchange between the client and the server

In addition, does the server need to repeatedly broadcast some sort of message to inform potential clients that it is up and running?

Thanks for your assistance.

4

2 回答 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.

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

不,这在不同的方向上起作用 - 客户端询问服务器是否正在运行。就像这样只是因为服务器不知道客户端,但客户端知道服务器。

于 2012-09-13T11:32:59.663 回答
2

关于“服务器是否需要重复广播某种消息”

有一些系统(服务器、服务)向积极使用IP 多播的感兴趣的客户端通告它们的位置(IP 地址、端口号)甚至附加信息(例如状态)。

使用 Internet Direct (Indy) UDP 组件很容易实现服务器端和客户端。

这是一个用于开源消息代理 Apache ActiveMQ 的 Delphi 的 IP 多播示例,带有完整的源代码:

使用 Delphi XE4 和 Indy 10.6 发现 ActiveMQ 代理

于 2012-09-13T14:25:17.687 回答