Solved

Console App Help...

Posted on 2004-04-01
19
1,081 Views
Last Modified: 2008-02-01
Hello,
 I have this code but I need some help with it

Program Project2;

{$APPTYPE CONSOLE}

Uses
  SysUtils, ScktComp;

Type
  TMyApp = Class(TObject)
    Public
      Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
  End;

Var
  MyApp: TMyApp; Server: TServerSocket;

Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Connected.') End;
Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Disconnected.') End;
Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn(Socket.ReceiveText) End;

Begin
  MyApp := TMyApp.Create;
  Server := TServerSocket.Create(nil);
  Server.OnClientConnect := MyApp.Connect;
  Server.OnClientDisconnect := MyApp.Disconnect;
  Server.OnClientRead := MyApp.Receive;
  Server.Port := 6000;
  Server.Active := True;
  While True Do ReadLn;
End.

But I think the
   While True Do ReadLn;

Is blocking the ServerSocket, how can I fix this?
I will give more points but this is all I have at the mo.

Thx Karamja
0
Comment
Question by:-Karamja-
  • 11
  • 7
19 Comments
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10734709
you might want to try adding a timer

set it interval property for say 3000 //every 3 seconds

Begin
 timer1:= TTimer.Create;
 timer1.enabled:= false;
 timer1.OnTImer:= MyTImer;
  MyApp := TMyApp.Create;
  Server := TServerSocket.Create(nil);
  Server.OnClientConnect := MyApp.Connect;
  Server.OnClientDisconnect := MyApp.Disconnect;
  Server.OnClientRead := MyApp.Receive;
  Server.Port := 6000;
  Server.Active := True;
  Timer1.Enabled:= True;
End.


procedure MyTimer(Sender: TObject);
var
 tmp: String;
begin
tmp:=  Server.Readln;
if tmp <> '' then
// DoSomething with tmp
end;


don't forget to free your timer & server on forms close


Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10734732
procedure MyTimer(Sender: TObject);
var
 tmp: String;
begin
tmp:=  Readln;
if tmp <> '' then
// DoSomething with tmp
end;


this will continue until you call timer1.enabled:= false;

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10734737
sorry

timer1:= TTimer.Create(nil);

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10734962
Program Project2;

{$APPTYPE CONSOLE}

Uses
  SysUtils, ScktComp, ExtCtrls;

Type
  TMyApp = Class(TObject)
    Public
      Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
      Procedure MyTimer(Sender: TObject);
  End;

Var
  MyApp: TMyApp; Server: TServerSocket;
  Timer1: TTimer;

Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Connected.') End;
Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Disconnected.') End;
Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn(Socket.ReceiveText) End;

procedure MyTimer(Sender: TObject);
var
 tmp: String;
begin
tmp:=  Readln;
if tmp <> '' then
begin
 //do something here
end;
end;
 

Begin
 Timer1:= TTimer.Create(nil);
 Timer1.Enabled:= false;
 Timer1.OnTimer:= MyTimer
  MyApp := TMyApp.Create;
  Server := TServerSocket.Create(nil);
  Server.OnClientConnect := MyApp.Connect;
  Server.OnClientDisconnect := MyApp.Disconnect;
  Server.OnClientRead := MyApp.Receive;
  Server.Port := 6000;
  Server.Active := True;
  Timer1.Enabled:= True
End.


you also need to figure out how you are going to free up your objects when program terminates

Timer1.Free
 Server.Free;


You might want to do it in the MyTimer event.

You check for some logic then free them

Shane
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10735106
[Error] Project1.dpr(29): Incompatible types: 'String' and 'procedure, untyped pointer or untyped parameter'
[Error] Project1.dpr(41): Incompatible types: 'method pointer and regular procedure'
[Error] Project1.dpr(14): Unsatisfied forward or external declaration: 'TMyApp.MyTimer'

??????????
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10735119
At this line btw
tmp:= Readln;
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735196
Building you an example right now


Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735229
program Project1;

uses
  Forms,
  Unit2 in 'Unit2.pas';

{$R *.res}

begin
 Server.Active := True;
 Timer.Enabled:= True;
end.





unit Unit2;

interface

uses
 SysUtils, ScktComp, ExtCtrls, Dialogs;

Type
  TMyApp = Class(TObject)
    Public
      Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
      Procedure MyTimer(Sender: TObject);
  End;

var
 MyApp: TMyApp;
 Server: TServerSocket;
 Timer: TTimer;
 ReceivedText: String;

implementation

Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Connected.') End;
Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn('Disconnected.') End;
Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket); Begin WriteLn(Socket.ReceiveText) End;

procedure TMyApp.MyTimer(Sender: TObject);
begin
 //
end;


initialization
begin
 Timer:= TTimer.Create(nil);
 Timer.Enabled:= false;
 Timer.OnTimer:= MyApp.MyTimer;
 MyApp := TMyApp.Create;
 Server := TServerSocket.Create(nil);
 Server.OnClientConnect := MyApp.Connect;
 Server.OnClientDisconnect := MyApp.Disconnect;
 Server.OnClientRead := MyApp.Receive;
 Server.Port := 6000;
end;

finalization
begin
 Timer.Free;
 Server.Free;
end;
end.
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10735329
Ok, thx for your quick reply but I think you messed up a bit.

I am making a console app but you have done this a a normal project with units

{$APPTYPE CONSOLE}
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735359
program Project1;
No, i no your doing a Console app. I just figured out the timer wont work.

Although, I added the second unit, so you could free the Objects

Try This,

Shane



{$APPTYPE CONSOLE}
uses
  Forms,
  Unit2 in 'Unit2.pas';


{$R *.res}

begin
 Server.Active := True;
 System.Readln;
end.


unit Unit2;

interface

uses
 SysUtils, ScktComp, ExtCtrls;

Type
  TMyApp = Class(TObject)
    Public
      Procedure Connect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Disconnect(Sender: TObject; Socket: TCustomWinSocket);
      Procedure Receive(Sender: TObject; Socket: TCustomWinSocket);
  End;

var
 MyApp: TMyApp;
 Server: TServerSocket;

implementation

Procedure TMyApp.Connect(Sender: TObject; Socket: TCustomWinSocket);
Begin
 WriteLn('Connected.')
End;

Procedure TMyApp.Disconnect(Sender: TObject; Socket: TCustomWinSocket);
Begin
 WriteLn('Disconnected.')
End;

Procedure TMyApp.Receive(Sender: TObject; Socket: TCustomWinSocket);
Begin
 WriteLn(Socket.ReceiveText)
End;


initialization
begin
 MyApp := TMyApp.Create;
 Server := TServerSocket.Create(nil);
 Server.OnClientConnect := MyApp.Connect;
 Server.OnClientDisconnect := MyApp.Disconnect;
 Server.OnClientRead := MyApp.Receive;
 Server.Port := 6000;
end;

finalization
begin
 MyApp.Free;
 Server.Free;
end;
end.
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10735561
Right even tho this code works we are back to step one,
Somethink is blocking it again
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735666
Something is blocking what?

The socket from receiving data?

SHane
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10735819
That or showing it
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735846
did you try doing any type of break points, or write statements at certain points to test ...


example, the OnReceive event

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10735849
I can't test it, cause i don't have anything coming across that port

Shane
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10736098
1) You could change port to test
2) http://127.0.0.1:6000 Should call the on connect event
0
 
LVL 11

Expert Comment

by:shaneholmes
ID: 10736195
What i believe you want to do is in fact hard to accommplish in a console app
rather than in a GUI app.
A GUI app typically sits idly waiting in the message loop for messages to come it to
process. Sockets create background threads that need to Synchronize to the
main threads for the socket events, and the synchronization is done using
messages. So, no message loop, no synchronization. And a console app typically
does not have a message loop, it sits waiting for console input events if it
is not a linear processing code flow anyway.

So i would make a little VCl app, using a main form with a memo as output
window instead of a console.

It is surely possible to get this to work with a console as well, but it
requires a whole lot more work.

Would you consider a invisible form?

A Borderless form?

SOmething other than a Console app?

Shane
0
 
LVL 19

Accepted Solution

by:
Melih SARICA earned 55 total points
ID: 10739220
Here is a running example

How to test:
 open internet explorer and type this address

   http://127.0.0.1:5555


 

program Project1;

{$APPTYPE CONSOLE}

uses
  sockets,windows;

type
  TmySocket = class(TObject)
    mServer : TTcpServer;
    public
      procedure Create;
      Procedure Destroy;
      property TCPServer : TTcpServer read mserver write mserver;
    protected
      Procedure mOnAccept (Sender: TObject; ClientSocket: TCustomIpClient);
  end;
var
  mysock : TmySocket;
  msg : tagMSG;
{ TmySocket }

procedure TmySocket.Create;
begin
  mServer:=TTcpServer.Create(nil);
end;

procedure TmySocket.Destroy;
begin
 mServer.Free;
end;

procedure TmySocket.mOnAccept(Sender: TObject;ClientSocket: TCustomIpClient);
var
   mbuf : pchar;
   dlen : integer;
   mstr : string ;
begin
   writeln(clientSocket.remotehost);
   mstr :=clientSocket.remotehost+ ' ->Just To see if that is send';
   ClientSocket.Sendln(mstr);
   ClientSocket.ReceiveBuf(mbuf,dlen,0);
end;

begin
  mysock.Create;
  mysock.TCPServer.LocalPort:='5555';
  mysock.TCPServer.OnAccept:=mysock.mOnAccept;
  mysock.TCPServer.Active:=true;
  while GetMessage(Msg, 0, 0, 0) <> BOOL(FALSE) do begin
   TranslateMessage(Msg);
   DispatchMessage(Msg);
  end;
  mysock.TCPServer.Active:=false;
  mysock.Destroy;

end.
0
 
LVL 2

Author Comment

by:-Karamja-
ID: 10739470
Thx, your code worked fine.
Also thx for your quick replys
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Virtuailstring tree compare node issue 14 105
Delphi application Soap connection 5 96
Making delphi communicate with a c# service 16 90
can't find the executable in Simulator 1 80
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now