Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ClientSocket in a Service Problem....

Status
Not open for further replies.

Timsta

Programmer
Jan 31, 2006
1
0
0
GB
Hiya,

I haven't used Delphi in ages, so I recon it must just be me. Here is what I'm trying to do:

I need to have a service that posts some text on port 80 then reads the result. Now, I can post the data with a ClientSocket on a form just fine, and I can write a service just fine. The problem comes when I try to use a clientsocket in a service. As soon as I use them together it just doesn't work! Well actually, it does work *if I do a showmessage just after I set the socket active!?* What's that all about?! lol

I am using a sniffer to check the network activity and there is nothing! (Unless I have a showmessage in there, and I obviously don't want to have to have a message pop up on my service)

Here is some of the code:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, scktcomp;

type
TService1 = class(TService)
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceContinue(Sender: TService; var Continued: Boolean);
procedure ServicePause(Sender: TService; var Paused: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
private
{ Private declarations }
public
function GetServiceController: TServiceController; override;
{ Public declarations }
end;

TSparkyThread = class(TThread)
ClientSocket1: TClientSocket;
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
public
procedure Execute; override;
end;


var
Service1: TService1;

implementation

var
SparkyThread: TSparkyThread;


{$R *.DFM}

procedure TSparkyThread.Execute;
begin
ClientSocket1 := TClientSocket.Create(application);
ClientSocket1.Port := 80;
ClientSocket1.Host := '192.168.1.100';
ClientSocket1.OnConnect := ClientSocket1Connect;

while not Terminated do
begin
Beep;
Sleep(10000);
ClientSocket1.Active:=True;
// ShowMessage('works if this line is uncommented');
end;

end;



procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
SparkyThread:=TSparkyThread.Create(False);
Started:=True;
end;

procedure TSparkyThread.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket1.Socket.SendText('some text');
ClientSocket1.Active:=False;
end;

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
Service1.Controller(CtrlCode);
end;

function TService1.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;

procedure TService1.ServiceContinue(Sender: TService;
var Continued: Boolean);
begin
SparkyThread.Resume;
Continued:=True;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
SparkyThread.Suspend;
Paused:=True;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
SparkyThread.Terminate;
Stopped:=True;
end;

end.

Many Thanks
Tim
 
I don't remember the Delphi sockets well (never used them), but I suppose they are message driven as most winsockets are.

Being so, you are not giving your code a chance to get the sockets messages from the queue (that is why your code works adding a ShowMessage).

Please, considere:

a) A thread dont get a message queue on creation, you need to "fire" the creation (something like saying the OS "this thread will receive messages"). You can do it calling PeekMessage with PM_NOREMOVE when the thread Execute procedure starts.

b) May be you need to peek the thread messages yourself and dispatch them (it dependes on how the whole thing works). In this case you dont need the starting PeekMessage - NO_REMOVE, as the first call to GetMessages will start the queue... but be sure the first call is made before any message arrive.

Code:
procedure MyThread.Execute;
  begin
    while not Terminated do GetMessages;
  end;

procedure MyThread.GetMessages;
  var
    Msg : TMsg;
  begin
    while not Terminated and PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
  end;

HTH.
buho (A).


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top