📄 udiclientcontext.pas
字号:
unit uDIClientContext;
interface
uses
Windows, SysUtils, WinSock2, uCriticalSection, uDIBuffer, uCircularBuffer, uDIProtocol;
type
//心跳结构
PTHeartBeatParam = ^THeartBeatParam;
THeartBeatParam = packed record
m_BeginTime: DWORD; //心跳时间
end;
//per-Handle
TDIClientContext = Class
public
m_pNext: TDIClientContext; //指向下一个DIClientChannel
m_Socket: TSocket; //绑定完成端口
m_CloseOverlap: OVERLAPPED; //重叠结构投递CloseSocket时用
m_KeyID: Word; //客户端标识
FLocalAddr: PSockAddr; //连接的本地地址
FRemoteAddr: PSockAddr; //连接的远程地址
m_nOutOfPendRecvIO: DWORD; //套节字上抛出的Recv数量
m_nOutOfPendSendIO: DWORD; //套节字上抛出的Send数量
m_nOutOfPendCloseSocket: DWORD; //套节字上抛出的CloseSocket数量
m_nOutOfPendIO: DWORD; //IOCP未决的I/O总数
private
m_HeartBeatParam: THeartBeatParam; //心跳结构
m_SendSequenceNumber: DWORD; //下一个发送序列号
m_ReadSequenceNumber: DWORD; //下一个接收序列号
m_CurrentSendSequenceNumber: DWORD; //当前发送序列号
m_CurrentReadSequenceNumber: DWORD; //当前接收序列号
private
sRemoteIP: String; //IP客户端
m_bClosed: Boolean; //该套接字是否被关闭
m_bPostCloseSocket: Boolean; //是否已经投递了关闭套接字的I/O
FRecvBuffer: TDIBuffer; //接收缓冲区
FSendBuffer: TDIBuffer; //发送缓冲区
FOutOfOrderBuffer: TDIBuffer; //记录没有按顺序完成的读I/O
//FRecvCircularBuffer: TCircularBuffer; //接收环形Buffer区
//FSendCircularBuffer: TCircularBuffer; //发送环形Buffer区
m_ContextLock: TCriticalSection; //临界
public
procedure EnterIOLoop(m_Op: IOEventType);
procedure ExitIOLoop(m_Op: IOEventType);
procedure SetHeartBeatParam(Time: DWORD);
procedure SetupOvlpClose; //该上下文是否还有未决的I/O
function IsOutOfPendIO(var nSend, nRecv, nClosed: Integer): Boolean;
published
property FClosed: Boolean read m_bClosed write m_bClosed;
property FPostCloseSocket: Boolean read m_bPostCloseSocket write m_bPostCloseSocket;
property FSocket: TSocket read m_socket write m_socket;
property FContextLock: TCriticalSection read m_ContextLock write m_ContextLock;
property RecvBuffer: TDIBuffer read FRecvBuffer write FRecvBuffer;
property SendBuffer: TDIBuffer read FSendBuffer write FSendBuffer;
//property RecvCircularBuffer: TCircularBuffer read FRecvCircularBuffer write FRecvCircularBuffer;
//property SendCircularBuffer: TCircularBuffer read FSendCircularBuffer write FSendCircularBuffer;
property FHeartBeatParam: THeartBeatParam read m_HeartBeatParam write m_HeartBeatParam;
property FRemoteIP: string read sRemoteIP write sRemoteIP;
property FCloseOverlap: OVERLAPPED read m_CloseOverlap;
public
procedure InitClientContext;
public
constructor Create;
destructor Destroy; override;
end;
implementation
constructor TDIClientContext.Create;
begin
inherited Create;
m_ContextLock := TCriticalSection.Create;
FOutOfOrderBuffer := nil;
FRecvBuffer := TDIBuffer.Create;
FSendBuffer := TDIBuffer.Create;
//FRecvCircularBuffer := TCircularBuffer.Create(RECV_CIRCULAR_BUFFER_SIZE);
//FSendCircularBuffer := TCircularBuffer.Create(SEND_CIRCULAR_BUFFER_SIZE);
InitClientContext;
end;
procedure TDIClientContext.InitClientContext;
begin
m_Socket := INVALID_SOCKET;
m_bClosed := FALSE;
m_bPostCloseSocket := FALSE;
m_KeyID := 0;
m_pNext := nil;
m_nOutOfPendRecvIO := 0;
m_nOutOfPendSendIO := 0;
m_nOutOfPendCloseSocket := 0;
m_nOutOfPendIO := 0;
m_SendSequenceNumber := 0;
m_ReadSequenceNumber := 0;
m_CurrentSendSequenceNumber := 0;
m_CurrentReadSequenceNumber := 0;
m_HeartBeatParam.m_BeginTime := 0;
sRemoteIP := '';
FRecvBuffer.InitBuffer;
FSendBuffer.InitBuffer;
//FRecvCircularBuffer.SetEmpty;
//FSendCircularBuffer.SetEmpty;
end;
procedure TDIClientContext.SetupOvlpClose;
begin
ZeroMemory(@m_CloseOverlap, SizeOf(m_CloseOverlap));
m_CloseOverlap.Offset := DWord(IOWSACloseSocket);
end;
destructor TDIClientContext.Destroy;
begin
FreeAndNil(FRecvBuffer);
FreeAndNil(FSendBuffer);
//FreeAndNil(FRecvCircularBuffer);
//FreeAndNil(FSendCircularBuffer);
FreeAndNil(m_ContextLock);
inherited Destroy;
end;
procedure TDIClientContext.EnterIOLoop(m_Op: IOEventType);
begin
case m_Op of
IOWSARecv:
Inc(m_nOutOfPendRecvIO);
IOWSASend:
Inc(m_nOutOfPendSendIO);
IOWSACloseSocket:
Inc(m_nOutOfPendCloseSocket);
end;
m_nOutOfPendIO := m_nOutOfPendRecvIO + m_nOutOfPendSendIO + m_nOutOfPendCloseSocket;
end;
procedure TDIClientContext.ExitIOLoop(m_Op: IOEventType);
begin
case m_Op of
IOWSARecv:
Dec(m_nOutOfPendRecvIO);
IOWSASend:
Dec(m_nOutOfPendSendIO);
IOWSACloseSocket:
Dec(m_nOutOfPendCloseSocket);
end;
m_nOutOfPendIO := m_nOutOfPendRecvIO + m_nOutOfPendSendIO + m_nOutOfPendCloseSocket;
end;
function TDIClientContext.IsOutOfPendIO(var nSend, nRecv, nClosed: Integer): Boolean;
begin
Result := m_nOutOfPendIO = 0;
nSend := m_nOutOfPendSendIO;
nRecv := m_nOutOfPendRecvIO;
nClosed := m_nOutOfPendCloseSocket;
end;
procedure TDIClientContext.SetHeartBeatParam(Time: DWORD);
begin
m_HeartBeatParam.m_BeginTime := Time;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -