I just want a simple console application to be able to act as a server.
Once I can talk to that with telnet I was going to write a basic client
and work my way up from there.
I can't even get as far as creating the server:
program ServerTest;
{$APPTYPE CONSOLE}
uses
SysUtils,IdTCPServer;
var
svr:TIdTCPServer;
begin
svr:= idtcpserver.create();
end.
It seems to expect an owner in the constructor, I am very new to delphi
but this does not seem to make sense within the context of a console app.
Can someone give me the bare bones of a server that accept connections
on a given port and prints whatever it receives on the screen?
Thanks
I've got as far as this now. It tells me
"[DCC Error] ServerTest.dpr(10): E2003 Undeclared identifier:
'TIdPeerThread'"
So, where is TIdPeerThread defined?
Thanks
program ServerTest;
{$APPTYPE CONSOLE}
uses
SysUtils,IdBaseComponent,IdComponent,IdTCPServer;
var
svr:TIdTCPServer;
procedure Execute(AThread: TIdPeerThread);
begin
end;
begin
svr:=tidtcpserver.Create();
svr.Bindings.DefaultPort := 1000;
svr.onexecute:=Execute;
svr.Active:=true;
while true do sleep(10000);
end.
> I'm trying to learn how to use indy. A lot of the examples I
> can find online assume I am embedding the indy component
> within a form.
They work exactly the same whether you drop them on a TForm or TDataModule
at design-time, or instantiate them dynamically in your run-time code
instead.
> I just want a simple console application to be able to act as a server.
Given the code you have shown, your console app is going to terminate right
away. You are creating the server object fine, but then you let the DPR
code exit without waiting on any kind of event or other termination
triggers. You need to perform some kind of waiting in order for the console
process to stay running for any length of time.
> I can't even get as far as creating the server:
Yes, you are. You are just not doing anything with it.
program ServerTest;
{$APPTYPE CONSOLE}
uses
SysUtils, IdTCPServer;
type
// VCL event handlers need to be methods of a class
TMyServerEvents = class
public
procedure ServerExecute(AThread: TIdPeerThread);
end;
procedure TMyServerEvents.ServerExecute(AThread: TIdPeerThread);
var
S: String;
begin
S := AThread.Connection.ReadLn;
WriteLn(Format('%s: %s', [AThread.Connection.Socket.Binding.PeerIP,
S]));
end;
var
svr: TIdTCPServer;
events: TMyServerEvents;
begin
svr := TIdTCPServer.Create(nil);
try
events := TMyServerEvents.Create;
try
svr.Port := 12345;
svr.OnExecute := events.ServerExecute;
svr.Active := True;
try
// wait for some signal that the app should shut down...
finally
svr.Active := False;
end;
finally
events.Free;
end;
finally
svr.Free;
end;
end.
To help you with using the server and its events, you might want to consider
putting the server into a TDataModule at design-time, and then you can
create the TDataModule at run-time.
Gambit
> I've got as far as this now. It tells me
>
> "[DCC Error] ServerTest.dpr(10): E2003 Undeclared identifier:
> 'TIdPeerThread'"
>
> So, where is TIdPeerThread defined?
There is no TIdPeerThread in Indy 10. It was replaced with TIdContext.
Gambit
> type
> // VCL event handlers need to be methods of a class
> TMyServerEvents = class
> public
> procedure ServerExecute(AThread: TIdPeerThread);
> end;
Sorry, I didn't notice you were using Indy 10 instead:
program ServerTest;
{$APPTYPE CONSOLE}
uses
SysUtils, IdIOHandler, IdTCPConnection, IdContext, IdTCPServer;
type
TMyServerEvents = class
public
procedure ServerExecute(AContext: TIdContext);
end;
procedure TMyServerEvents.ServerExecute(AContext: TIdPeerThread);
var
S: String;
begin
S := AContext.Connection.IOHandler.ReadLn;
WriteLn(Format('%s: %s', [AContext.Connection.Socket.Binding.PeerIP,
S]));
end;
Gambit
I was working from source code in the Official Indy 10 pdf manual. On
page 106. They should probably update their examples:
Server Source Code
unit ServerMain;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
IdBaseComponent, IdComponent, IdTCPServer;
type
TformMain = class(TForm)
IdTCPServer1: TIdTCPServer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
ZipCodeList: TStrings;
public
end;
var
formMain: TformMain;
implementation
{R *.DFM}
procedure TformMain.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
AThread.Connection.WriteLn('Indy Zip Code Server Ready.');
end;
procedure TformMain.IdTCPServer1Execute(AThread: TIdPeerThread);
var
sCommand: string;
begin
with AThread.Connection do
begin
sCommand := ReadLn;
if SameText(sCommand, 'QUIT') then
begin
Disconnect;
end
else if SameText(Copy(sCommand, 1, 8), 'ZipCode ') then
begin
WriteLn(ZipCodeList.Values[Copy(sCommand, 9, MaxInt)]);
end;
end;
end;
procedure TformMain.FormCreate(Sender: TObject);
begin
ZipCodeList := TStringList.Create;
ZipCodeList.LoadFromFile(ExtractFilePath(Application.EXEName) +
'ZipCodes.dat');
end;
procedure TformMain.FormDestroy(Sender: TObject);
begin
ZipCodeList.Free;
end;
end.
I understand that I need to suspend the main thread. The problem was
that it was not even compiling... I was using idtcpserver.create();
instead of Tidtcpserver.create();
Anyway thanks for the examples.
Mark