destructor TAlarmWorkThread.Destroy;
begin
  inherited;
end;
procedure TAlarmWorkThread.Execute;
var
   BytesTransferred: DWORD ;
   PHandleData: LPPerHandelData;
   Block: PBlock;
   Flags: DWORD ;
   BodySize,BytesSend,ErrCode : Integer;
   Cmd : Word;
begin
  while (not self.Terminated) do
  begin
    //查询IOCP状态(数据读写操作是否完成)
    if (GetQueuedCompletionStatus(FCompletePort, BytesTransferred, DWORD(PHandleData), POverlapped(Block), INFINITE) = true) then
    begin
        //FThreadPool.PShowCommGauge();
        //工作线程被Post消息提示退出
        if (PHandleData = nil) then
        begin
           FThreadPool.PShowRealMsg(APP_MSGTYPE_THREAD,'控制信息','报警控制TCP服务器释放相关资源,成功关闭服务!');
           Exit;
        end;
        //如果链路断开,释放相关资源
        if (BytesTransferred = 0) then
        begin
           FThreadPool.PShowRealMsg(APP_MSGTYPE_THREAD,'控制信息','客户端【Addr=' + PHandleData.PSrcAddr + '】'+ PHandleData.PSrcName  + '断开,TCP服务器释放相关资源!');
           //清除该客户端相关资源
           FCloseConnAndFree(PHandleData);
           Continue;
        end;
        with Block^.Data do
        try
          case Block^.Data.OperType of
            APP_OPERTYPE_RECV:
            begin
              FRecAndMakePac(PHandleData,Block,BytesTransferred);
              Block.Data.IsUse := False;
              Block.IsUse := False;
              Block := nil;
              FReceiveData(PHandleData,Block);
              Continue;
            end;
          
            APP_OPERTYPE_SEND:
            begin
              Dec(wsaBuffer.len, BytesTransferred);
              if wsaBuffer.len <= 0 then
              begin
                { 发送完成,将Block置空,返回到FBlock的可使用的缓区中 }
                //FSendHandlePacByCmd(PHandleData,Block,BytesTransferred);
                Block.Data.IsUse := False;
                Block.IsUse := False;
                Block := nil;
              end else
              begin
                { 数据还没发送完成,继续发送 }
                Flags := 0;
                Inc(Pbyte(wsaBuffer.buf), BytesTransferred);
                FillChar(Overlapped, SizeOf(Overlapped), 0);
                if SOCKET_ERROR = WSASend( PHandleData.Socket, @wsaBuffer, 1, @BytesSend,Flags, @Overlapped, nil) then
                begin
                  ErrCode := WSAGetLastError;
                  if ErrCode <> ERROR_IO_PENDING then
                    begin
                      FThreadPool.PShowRealMsg(APP_MSGTYPE_THREAD,'控制信息','客户端【Addr=' + PHandleData.PSrcAddr + '】异常断开,TCP服务器释放相关资源!');
                      FCloseConnAndFree(PHandleData);//清除该客户端相关资源
                      Continue;
                    end;
                end;
              end;
            end;
          end;
      except
      end;
    end else begin
       if (PHandleData <> nil ) then
       begin
          FThreadPool.PShowRealMsg(APP_MSGTYPE_THREAD,'视频服务','客户端【Addr=' + PHandleData.PSrcAddr + '】异常断开,TCP服务器释放相关资源!');
          FCloseConnAndFree(PHandleData);//清除该客户端相关资源
       end;
    end;
  end;
end;
function TAlarmWorkThread.FRecAndMakePac(PHandleData: LPPerHandelData;Block: PBlock; Transfered: DWORD): Integer;
begin
  PHandleData.RingBuffer.WriteBuffer(Block.Data.Buffer,Transfered);
  FCheckisCompletePac(PHandleData);
end;
function TAlarmWorkThread.FCheckisCompletePac(PHandleData: LPPerHandelData): Integer;
var
  Tmp:string;
  PackedLen,BodySize: Word;
  PackedHead: TNetAlarmHead;
  dataSize : LongInt;
  RevBuffer: array [0..MAX_BUFFER_LEN] of Char;
  WimpPacket: TWimpMsg;
  cmd:Word;
begin
    dataSize := PHandleData.RingBuffer.GetDataCount();
    if dataSize < SizeOf(TNetAlarmHead) then Exit; //如果不够包头长就退出
    PHandleData.RingBuffer.Copybuffer(PackedHead,SizeOf(TNetAlarmHead));
    cmd := ntohs(PackedHead.Command_Id);
    PackedLen := FGetLenOfBodyByHeader(cmd); //包体长度
    if PackedLen < 0 then
    begin
      PHandleData.RingBuffer.Readbuffer(PackedHead,SizeOf(TNetAlarmHead));
      FCheckisCompletePac(PHandleData); //嵌套执行
    end else begin
      if dataSize >= (PackedLen + SizeOf(TNetAlarmHead)) then
      begin
        PHandleData.RingBuffer.Readbuffer(PackedHead,SizeOf(TNetAlarmHead));
        PHandleData.RingBuffer.Readbuffer(RevBuffer,PackedLen);
        FMergePacked(WimpPacket,cmd,RevBuffer);
        FHandleRecPacket(WimpPacket,cmd,PHandleData);
        FCheckisCompletePac(PHandleData); //嵌套执行
      end;
    end;
end;
function TAlarmWorkThread.FSendPacket(PHandleData: LPPerHandelData; var HeadBuf,BodyBuf; HeadLen, BodyLen: Integer): Integer;
var
  ErrCode: Integer;
  Flags, Transfer: Cardinal;
  Block: PBlock;
begin
  Result := 0;
  Block := PHandleData.MemoryBuffer.AllocBlock;
  with Block^.Data do
  begin
    Flags := 0;
    OperType := APP_OPERTYPE_SEND;
    FillChar(Buffer, SizeOf(Buffer), 0);
    Move(HeadBuf,Buffer,HeadLen);
    Move(BodyBuf,Buffer[HeadLen],BodyLen);
    FillChar(Overlapped, SizeOf(Overlapped), 0);
    wsaBuffer.buf := @buffer;
    wsaBuffer.len := HeadLen + BodyLen;
    if SOCKET_ERROR = WSASend(PHandleData.Socket, @wsaBuffer, 1, @Transfer, Flags, @Overlapped, nil) then
    begin
      ErrCode := WSAGetLastError;
      if ErrCode <> ERROR_IO_PENDING then
      begin
        Result := SOCKET_ERROR;
      end;
    end;
  end;
end;
 
function TAlarmWorkThread.FCloseConnAndFree(PHandleDataPPerHandelData): Integer;
var PIoDataID : Integer;
    Llt : TList;
begin
   Result := 0;
   PIoDataID := FGetClientID(PHandleData);
   FThreadPool.PUpdateOnLine(PHandleData.PSrcType,PHandleData.PSrcAddr,False);
   FThreadPool.PShowRealMsg(APP_MSGTYPE_THREAD,'控制信息','客户端【登录名=' + PHandleData.PSrcAddr + '】'+ PHandleData.PSrcName  + '断开,TCP服务器释放相关资源!');
   if PIoDataID >=0 then
   begin
      FThreadPool.PUpdateCount(PHandleData.PSrcType,APP_UPDATECOUNT_DELETE);
      Llt := FAlarmSocketLists.LockList();
      Llt.Delete(PIoDataID);
      FAlarmSocketLists.UnlockList;
      shutdown(PHandleData.Socket,FD_CLOSE);
      closesocket(PHandleData.Socket);
      FreeAndNil(PHandleData.MemoryBuffer);
      FreeAndNil(PHandleData.RingBuffer);
      GlobalFree(DWORD(PHandleData));
   end;
end;
function TAlarmWorkThread.FGetClientID(APhandle: LPPerHandelData): integer;
var i:Integer;
    Llt:TList;
begin
  Result := -1;
  try
    Llt := FAlarmSocketLists.LockList();
    for i:=0 to Llt.Count - 1 Do
    begin
      if LPPerHandelData(Llt.Items) = APhandle then
      begin
         Result := i;
         Break;
      end;
    end;
  finally
    FAlarmSocketLists.UnlockList;
  end;
end;