zoukankan      html  css  js  c++  java
  • TDiocpTcpServer socket哈希表

    uses utils_hashs
    
    var FOnlineContextList : TDHashTable;
    
    FOnlineContextList := TDHashTable.Create(10949);
    
    procedure TDiocpTcpServer.AddToOnlineList(pvObject: TIocpClientContext);
    begin
      FLocker.lock('AddToOnlineList');
      try
        FOnlineContextList.Add(pvObject.FSocketHandle, pvObject);
        if DataMoniter <> nil then
        begin
          DataMoniter.CalcuMaxOnlineCount(FOnlineContextList.Count);
        end;
      finally
        FLocker.unLock;
      end;
    end;
    
    function TDiocpTcpServer.FindContext(pvSocketHandle:TSocket):
        TIocpClientContext;
    {$IFDEF USE_HASHTABLE}
    
    {$ELSE}
    var
      lvHash:Integer;
      lvObj:TIocpClientContext;
    {$ENDIF}
    begin
      FLocker.lock('FindContext');
      try
        {$IFDEF USE_HASHTABLE}
        Result := TIocpClientContext(FOnlineContextList.FindFirstData(pvSocketHandle));
        {$ELSE}
        Result := nil;
        lvHash := pvSocketHandle and SOCKET_HASH_SIZE;
        lvObj := FClientsHash[lvHash];
        while lvObj <> nil do
        begin
          if lvObj.FRawSocket.SocketHandle = pvSocketHandle then
          begin
            Result := lvObj;
            break;
          end;
          lvObj := lvObj.FNextForHash;
        end;
        {$ENDIF}
      finally
        FLocker.unLock;
      end;
    end;
    
    procedure TDiocpTcpServer.RemoveFromOnOnlineList(pvObject: TIocpClientContext);
    {$IFDEF USE_HASHTABLE}
      {$IFDEF DEBUG_ON}
        var
          lvSucc:Boolean;
      {$ENDIF}
    {$ELSE}
    var
      lvHash:Integer;
    {$ENDIF}
    begin
    {$IFDEF USE_HASHTABLE}
      FLocker.lock('RemoveFromOnOnlineList');
      try
        {$IFDEF DEBUG_ON}
        lvSucc := FOnlineContextList.DeleteFirst(pvObject.FSocketHandle);
        Assert(lvSucc);
        {$ELSE}
        FOnlineContextList.DeleteFirst(pvObject.FSocketHandle);
        {$ENDIF}
      finally
        FLocker.unLock;
      end;
    {$ELSE}
      FOnlineContextList.remove(pvObject);
    
      FLocker.lock('RemoveFromOnOnlineList');
      try
        // hash
        if pvObject.FPreForHash <> nil then
        begin
          pvObject.FPreForHash.FNextForHash := pvObject.FNextForHash;
          if pvObject.FNextForHash <> nil then
            pvObject.FNextForHash.FPreForHash := pvObject.FPreForHash;
        end else
        begin     // first ele
          lvHash := pvObject.RawSocket.SocketHandle and SOCKET_HASH_SIZE;
          FClientsHash[lvHash] := pvObject.FNextForHash;
          if FClientsHash[lvHash] <> nil then
            FClientsHash[lvHash].FPreForHash := nil;
        end;
      finally
        FLocker.unLock;
      end;
    
      pvObject.FNextForHash := nil;
      pvObject.FPreForHash := nil;
    {$ENDIF}
    end;
    
    function TDiocpTcpServer.OnlineClientsCallBack(pvCallBack: TOnContextEvent;
        pvTag: Integer; pvTagData: Pointer): Integer;
    var
      I:Integer;
      lvBucket: PDHashData;
      lvContext: TIocpClientContext;
    begin
      Result := 0;
      FLocker.lock('GetOnlineContextList');
      try
        for I := 0 to FOnlineContextList.BucketSize - 1 do
        begin
          lvBucket := FOnlineContextList.Buckets[I];
          while lvBucket<>nil do
          begin
            if lvBucket.Data <> nil then
            begin
              lvContext := TIocpClientContext(lvBucket.Data);
              if lvContext.LockContext(STRING_EMPTY, nil) then
              try
                pvCallBack(lvContext, pvTag, pvTagData);
                Inc(Result);
              finally
                lvContext.UnLockContext(STRING_EMPTY, nil);
              end;
            end;
            lvBucket:=lvBucket.Next;
          end;
        end;
      finally
        FLocker.unLock;
      end;
    
    end;
    
    function TDiocpTcpServer.PostBufferToOnlineClients(pvBuf:Pointer;
        pvLen:Integer; pvCopyBuf: Boolean = true; pvTag: Integer = 0; pvTagData:
        Pointer = nil): Integer;
    var
      I:Integer;
      lvBucket: PDHashData;
      lvContext: TIocpClientContext;
    begin
      Result := 0;
      FLocker.lock('GetOnlineContextList');
      try
        for I := 0 to FOnlineContextList.BucketSize - 1 do
        begin
          lvBucket := FOnlineContextList.Buckets[I];
          while lvBucket<>nil do
          begin
            if lvBucket.Data <> nil then
            begin
              lvContext := TIocpClientContext(lvBucket.Data);
              if lvContext.PostWSASendRequest(pvBuf, pvlen, pvCopyBuf, pvTag, pvTagData) then
              begin
                Inc(Result);
              end;
            end;
            lvBucket:=lvBucket.Next;
          end;
        end;
      finally
        FLocker.unLock;
      end;
    end;
    

     TCP服务端使用哈希表记录TCP在线客户端。哈希表可以缓存大量在线客户记录,且哈希查找速度非常快。 

  • 相关阅读:
    OSError: cannot open resource(pillow错误处理)
    boost 库中文教程
    博客案例
    requests模块
    浅析Python中的struct模块
    面试基础知识点总结
    ant安装、环境变量配置及验证
    TestNG学习-001-基础理论知识
    selenium 常见面试题以及答案
    HTML5
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/13518315.html
Copyright © 2011-2022 走看看