JDaniel
JDaniel

Reputation: 102

Indy 10 TCP Client Server - testing for open communication channel

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.

Upvotes: 3

Views: 3235

Answers (2)

mjn
mjn

Reputation: 36654

On "does the server need to repeatedly broadcast some sort of message":

There are systems (servers, services) which advertise their location (IP adress, port number) and even additional information (for example a status) to interested clients actively using IP Multicast.

It is easy to implement both server- and client side with Internet Direct (Indy) UDP components.

Here is a IP multicast example for Delphi for the open source message broker Apache ActiveMQ with full source code:

Discover ActiveMQ brokers with Delphi XE4 and Indy 10.6

Upvotes: 2

TLama
TLama

Reputation: 76713

How to verify if it's possible to connect to a TCP server ?

To your first question; definitely wrap the connection attempt to a separate thread, which you'll run when your splash screen shows. In that thread you can simply try to Connect and catch the exception. If the exception is raised, the connection failed. If not, you were able to connect. For the notification about this state I would use custom messages, which you'll send to a splash screen form like shown in the following pseudocode:

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.

Does the server need to repeatedly broadcast some sort of message to inform potential clients that is running ?

No, this works in a different direction - client asks server if it's running. It's like that simply because server doesn't know clients, but client knows server.

Upvotes: 2

Related Questions