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在线客户端。哈希表可以缓存大量在线客户记录,且哈希查找速度非常快。
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/13518315.html

浙公网安备 33010602011771号