最近在写一个关于socket通讯的程序,用的是完成端口,再应用程序的模式下已经调试完毕,运行正常,现在想把他注册成为一个windows的服务程序,因为以前很少接触服务程序,试着写了一下,发现,服务可以启动,但是无法暂停和停止
我的思路是:
1.在servicestart里面初始化套接字,创建完成端口等操作(这里感觉没啥问题,服务可以启动)
2.在serviceexcute里面监听端口(问题1:因为进程会阻塞再socket的listen里,感觉是不是停止服务的时候,线程还一直阻塞再这里,导致无法停止服务?)
3.在serviestop里面关闭监听的端口(问题2:以前都是用serversocket控件做的,第一次用完成端口,不知道怎么关闭监听的端口)

解决方案 »

  1.   

      service1.AllowPause;
      service1.AllowStop这两个属性设置一下,一个是设置是否允许暂停的,一个是设置是否允许停止的。
      

  2.   

    再servicestop里调用了WSACancelBlockingCall 还是不能停止服务;
      

  3.   

    你是不是在主线程里使用了堵塞的SOCKET? 
      

  4.   

    程序代码
    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;
      

  5.   

    ServiceStart(Sender: TService; var Started: Boolean);
    ServiceStop(Sender: TService; var Stopped: Boolean);
    ServicePause(Sender: TService; var Paused: Boolean);
    ServiceContinue(Sender: TService; var Continued: Boolean);
      

  6.   

    试试做如下调整:
    ServiceStart事件里面去绑定套接字。
    ServiceExecute事件里面仅仅处理WSAAccept,并在While循环里面增加Sleep(0)。
    ServiceStop事件里面,首先设置KeepListening为False,然后再执行其它操作。
      

  7.   

    转帖:讨论C/S结构TCP服务器的算法
      

  8.   

    转帖:VC完整个人代理服务器应用程序代码请查看PostQueuedCompletionStatus函数的用法。
      

  9.   

    socket阻塞?你試著closesocket看看
      

  10.   

      while KeepListening do
      begin
        Len :=sizeof(sti);
        FillChar(sti, Len, #0);
        Acceptsc :=WSAAccept(Listensc, @Sti, @Len, Nil, 0);
      end;
    这是个死循环吧
      

  11.   

    Acceptsc :=WSAAccept(Listensc, @Sti, @Len, Nil, 0);另外创建个线程, WSAAccept放到新建的线程中去
      

  12.   

    服务程序 本身就可以 暂停,和停止。 查查 MSDN