[英]Indy TCP Server is not working from a service?
I want to run the Indy Server from a service and I used the following code but nothing happens. 我想从服务运行Indy Server,我使用了以下代码,但没有任何反应。 When I run the service I don't receive any exceptions on starting the server but I don't receive "Connected" message either when I try to connect. 当我运行该服务时,在启动服务器时没有收到任何异常,但在尝试连接时也没有收到“已连接”消息。 Am I doing it wrong or this thing it's not possible ? 我做错了还是这件事不可能? The server code was tested in a normal application and it's ok, it receives connections. 服务器代码已在普通应用程序中经过测试,可以,它可以接收连接。
I just started to learn services and I read some tutorials and they say that a very common use of a service is to check for updates for your application so I think my server should work... 我刚刚开始学习服务,并且阅读了一些教程,他们说服务的一种非常普遍的用法是检查应用程序的更新,因此我认为我的服务器应该可以工作。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdContext;
type
TMarusTestService = class(TService)
IdTCPServer1: TIdTCPServer;
procedure ServiceExecute(Sender: TService);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure IdTCPServer1Execute(AContext: TIdContext);
public
function GetServiceController: TServiceController; override;
end;
var
MarusTestService: TMarusTestService;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
MarusTestService.Controller(CtrlCode);
end;
function TMarusTestService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TMarusTestService.IdTCPServer1Execute(AContext: TIdContext);
var f:textfile;
begin
AssignFile(f,'f:\service.txt');
Rewrite(f);
Writeln(f,'Connected');
CloseFile(f);
repeat
AContext.Connection.Socket.ReadLongWord;
AContext.Connection.Socket.Write($93667B01);
until false;
end;
procedure TMarusTestService.ServiceExecute(Sender: TService);
var f:textfile;
begin
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('192.168.1.2', 1280);
try
IdTCPServer1.Active:=True;
except
on E: Exception do
begin
AssignFile(f,'f:\service.txt');
Rewrite(f);
Writeln(f,'Exception: '+E.ClassName+#13+E.Message);
CloseFile(f);
end;
end;
while not Terminated do
ServiceThread.ProcessRequests(true);
end;
procedure TMarusTestService.ServiceStart(Sender: TService;
var Started: Boolean);
begin
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('192.168.1.2', 280);
IdTCPServer1.Active:=True;
end;
procedure TMarusTestService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
IdTCPServer1.Active:=false;
end;
end.
Your service's OnExecute
handler is wiping out the TIdTCPServer.Binding
collection after the server is already activated. 服务已激活后 ,服务的OnExecute
处理程序将清除TIdTCPServer.Binding
集合。 Just get rid of the OnExecute
handler completely, let TService
handle SCM requests on its own for you. 只需完全摆脱OnExecute
处理程序,让TService
自行为您处理SCM请求。 Your OnStart
handler is already activating the TCP server, that is good enough (just be sure to set Started := True
, and Stopped := True
in the OnStop
event). 您的OnStart
处理程序已经在激活TCP服务器,这已经足够了(只需确保在OnStop
事件中将Started := True
设置为Stopped := True
OnStop
)。
As for your TIdTCPServer
events, you should move your 'Connected'
log message to the OnConnect
event, and get rid of the loop inside the OnExecute
event (since the event is already looped by TIdTCPServer
for you). 至于您的TIdTCPServer
事件,应将'Connected'
日志消息移至OnConnect
事件,并摆脱OnExecute
事件内部的循环(因为TIdTCPServer
已经为您循环了该事件)。
Try something more like this: 尝试更多类似这样的方法:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, IdContext,
SyncObjs;
type
TMarusTestService = class(TService)
IdTCPServer1: TIdTCPServer;
procedure ServiceCreate(Sender: TObject);
procedure ServiceDestroy(Sender: TObject);
procedure ServiceStart(Sender: TService; var Started: Boolean);
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
procedure IdTCPServer1Connect(AContext: TIdContext);
procedure IdTCPServer1Disconnect(AContext: TIdContext);
procedure IdTCPServer1Execute(AContext: TIdContext);
private
CS: TCriticalSection;
procedure Log(const Msg: String);
public
function GetServiceController: TServiceController; override;
end;
var
MarusTestService: TMarusTestService;
implementation
{$R *.DFM}
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
MarusTestService.Controller(CtrlCode);
end;
function TMarusTestService.GetServiceController: TServiceController;
begin
Result := ServiceController;
end;
procedure TMarusTestService.ServiceCreate(Sender: TObject);
begin
CS := TCriticalSection.Create;
end;
procedure TMarusTestService.ServiceDestroy(Sender: TObject);
begin
CS.Free;
end;
procedure TMarusTestService.Log(const Msg: String);
const
LogFileName = 'f:\service.txt';
var
f: TextFile;
begin
CS.Enter;
try
AssignFile(f, LogFileName);
if FileExists(LogFileName) then
Append(f)
else
Rewrite(f);
try
WriteLn(f, '[', DateTimeToStr(Now), '] ', Msg);
finally
CloseFile(f);
end;
finally
CS.Leave;
end;
end;
procedure TMarusTestService.IdTCPServer1Connect(AContext: TIdContext);
begin
Log('Connected');
end;
procedure TMarusTestService.IdTCPServer1Disconnect(AContext: TIdContext);
begin
Log('Disconnected');
end;
procedure TMarusTestService.IdTCPServer1Execute(AContext: TIdContext);
begin
AContext.Connection.Socket.ReadLongWord;
AContext.Connection.Socket.Write($93667B01);
end;
procedure TMarusTestService.ServiceStart(Sender: TService; var Started: Boolean);
begin
IdTCPServer1.Bindings.Clear;
IdTCPServer1.Bindings.Add.SetBinding('192.168.1.2', 280, Id_IPv4);
try
IdTCPServer1.Active := True;
except
on E: Exception do
begin
Log('Exception: (' + E.ClassName + ') ' + E.Message);
Win32ErrCode := 0;
ErrCode := 1;
Started := False;
Exit;
end;
end;
Log('Service Started');
Started := True;
end;
procedure TMarusTestService.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
IdTCPServer1.Active := False;
Log('Service Stopped');
Stopped := True;
end;
end.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.