最近在写一个关于socket通讯的程序,用的是完成端口,再应用程序的模式下已经调试完毕,运行正常,现在想把他注册成为一个windows的服务程序,因为以前很少接触服务程序,试着写了一下,发现,服务可以启动,但是无法暂停和停止
我的思路是:
1.在servicestart里面初始化套接字,创建完成端口等操作(这里感觉没啥问题,服务可以启动)
2.在serviceexcute里面监听端口(问题1:因为进程会阻塞再socket的listen里,感觉是不是停止服务的时候,线程还一直阻塞再这里,导致无法停止服务?)
3.在serviestop里面关闭监听的端口(问题2:以前都是用serversocket控件做的,第一次用完成端口,不知道怎么关闭监听的端口)
我的思路是:
1.在servicestart里面初始化套接字,创建完成端口等操作(这里感觉没啥问题,服务可以启动)
2.在serviceexcute里面监听端口(问题1:因为进程会阻塞再socket的listen里,感觉是不是停止服务的时候,线程还一直阻塞再这里,导致无法停止服务?)
3.在serviestop里面关闭监听的端口(问题2:以前都是用serversocket控件做的,第一次用完成端口,不知道怎么关闭监听的端口)
service1.AllowStop这两个属性设置一下,一个是设置是否允许暂停的,一个是设置是否允许停止的。
procedure TfDataCollectionService.ServiceStart(Sender: TService;
var Started: Boolean);
var
wsData :TWSAData;
begin
if WSAStartup($202, wsData) <>0 then
begin
Started :=False;
WSACleanup;
exit;
end;
Started :=True;
end;procedure TfDataCollectionService.ServiceExecute(Sender: TService);
var
sto, sti :TSockAddr;
Len :Integer;
Acceptsc :TSocket;
ClientPort :Integer;
ClientIPAddress :Array[0..47] of Char;
RegisterStr :Array[0..1023] of Char;
PerIOData :LPPER_IO_OPERATION_DATA;
PerHandleData :LPPER_HANDLE_DATA;
Flags :DWORD;
RecvBytes :DWORD;
WorkerPointer :Pointer;
begin
Listensc :=WSASocket(AF_INET, SOCK_STREAM, 0, Nil, 0, WSA_FLAG_OVERLAPPED);
if Listensc =SOCKET_ERROR then
begin WSACleanup;
exit;
end;
//***************绑定套接*************************
sto.sin_family :=AF_INET;
sto.sin_port :=htons(5000);
sto.sin_addr.S_addr :=htonl(INADDR_ANY);
if WinSock2.bind(Listensc, @sto, sizeof(sto)) =SOCKET_ERROR then
begin
closesocket(Listensc);
WSACleanup;
exit;
end;
listen(Listensc, 5);
while KeepListening do
begin
Len :=sizeof(sti);
FillChar(sti, Len, #0);
Acceptsc :=WSAAccept(Listensc, @Sti, @Len, Nil, 0);
end;
end;procedure TfDataCollectionService.ServiceStop(Sender: TService;
var Stopped: Boolean);
begin
WSACancelBlockingCall;
CloseSocket(Listensc );
end;
ServiceStop(Sender: TService; var Stopped: Boolean);
ServicePause(Sender: TService; var Paused: Boolean);
ServiceContinue(Sender: TService; var Continued: Boolean);
ServiceStart事件里面去绑定套接字。
ServiceExecute事件里面仅仅处理WSAAccept,并在While循环里面增加Sleep(0)。
ServiceStop事件里面,首先设置KeepListening为False,然后再执行其它操作。
begin
Len :=sizeof(sti);
FillChar(sti, Len, #0);
Acceptsc :=WSAAccept(Listensc, @Sti, @Len, Nil, 0);
end;
这是个死循环吧