Skip to content

Commit

Permalink
* StringServer
Browse files Browse the repository at this point in the history
  • Loading branch information
ymofen committed Dec 20, 2016
1 parent 9c1b699 commit ef4173a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 47 deletions.
Binary file added doc/D7退出后出现AV的解决办法.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 34 additions & 47 deletions source/diocp_ex_server.pas
Expand Up @@ -16,7 +16,8 @@
interface

uses
diocp_tcp_server, utils_buffer, utils_safeLogger, SysUtils, Classes;
diocp_tcp_server, utils_rawPackage, utils_safeLogger, SysUtils, Classes,
utils_strings;

type
TDiocpExContext = class;
Expand All @@ -31,7 +32,7 @@ TDiocpStringContext = class;

TDiocpExContext = class(TIocpClientContext)
private
FCacheBuffer: TBufferLink;
FCacheBuffer: TRawPackage;
FRecvData: array of Byte;
protected
procedure OnRecvBuffer(buf: Pointer; len: Cardinal; ErrCode: WORD); override;
Expand Down Expand Up @@ -99,19 +100,14 @@ TDiocpStringTcpServer = class(TDiocpExTcpServer)

implementation

uses
utils_strings;


constructor TDiocpExContext.Create;
begin
inherited Create;
FCacheBuffer := TBufferLink.Create();
end;

destructor TDiocpExContext.Destroy;
begin
FCacheBuffer.Free;
inherited Destroy;
end;

Expand All @@ -120,7 +116,8 @@ destructor TDiocpExContext.Destroy;
procedure TDiocpExContext.DoCleanUp;
begin
inherited DoCleanUp;
FCacheBuffer.clearBuffer;
FCacheBuffer.FEndBytesLength := 0;
FCacheBuffer.FStartBytesLength := 0;
end;

procedure TDiocpExContext.OnRecvBuffer(buf: Pointer; len: Cardinal; ErrCode: WORD);
Expand All @@ -137,57 +134,48 @@ procedure TDiocpExContext.OnRecvBuffer(buf: Pointer; len: Cardinal; ErrCode: WOR

lvOwner:TDiocpExTcpServer;

lvPtr:PByte;

begin
lvOwner := TDiocpExTcpServer(Owner);
lvStartData := @lvOwner.FStartData[0];
lvStartDataLen := lvOwner.FStartDataLen;
lvEndData := @lvOwner.FEndData[0];
lvEndDataLen := lvOwner.FEndDataLen;

FCacheBuffer.AddBuffer(buf, len);

while FCacheBuffer.validCount > 0 do
if (FCacheBuffer.FEndBytesLength = 0) and (FCacheBuffer.FStartBytesLength = 0) then
begin
// 标记读取的开始位置,如果数据不够,进行恢复,以便下一次解码
FCacheBuffer.markReaderIndex;
SetPackageMaxLength(@FCacheBuffer, lvOwner.FMaxDataLen);
lvStartData := @lvOwner.FStartData[0];
lvStartDataLen := lvOwner.FStartDataLen;
lvEndData := @lvOwner.FEndData[0];
lvEndDataLen := lvOwner.FEndDataLen;

if lvStartDataLen > 0 then
begin
// 不够数据,跳出
if FCacheBuffer.validCount < lvStartDataLen + lvEndDataLen then Break;

j := FCacheBuffer.SearchBuffer(lvStartData, lvStartDataLen);
if j = -1 then
begin // 没有搜索到开始标志
FCacheBuffer.clearBuffer();
Exit;
end else
begin
// 跳过开头标志
FCacheBuffer.Skip(j + lvStartDataLen);
end;
SetLength(FCacheBuffer.FStartBytes, lvStartDataLen);
Move(lvStartData^, FCacheBuffer.FStartBytes[0], lvStartDataLen);
FCacheBuffer.FStartBytesLength := lvStartDataLen;
end;

// 不够数据,跳出
if FCacheBuffer.validCount < lvEndDataLen then
if lvEndDataLen > 0 then
begin
FCacheBuffer.restoreReaderIndex;
Break;
SetLength(FCacheBuffer.FEndBytes, lvEndDataLen);
Move(lvEndData^, FCacheBuffer.FEndBytes[0], lvEndDataLen);
FCacheBuffer.FEndBytesLength := lvEndDataLen;
end;
ResetPacakge(@FCacheBuffer);
end;

j := FCacheBuffer.SearchBuffer(lvEndData, lvEndDataLen);
if j <> -1 then
lvPtr := PByte(buf);
for i := 0 to len -1 do
begin
r := InputBuffer(@FCacheBuffer, lvPtr^);
inc(lvPtr);
if r = 1 then
begin
SetLength(FRecvData, j);
FCacheBuffer.readBuffer(@FRecvData[0], j);
OnDataAction(@FRecvData[0], j);
FCacheBuffer.Skip(lvEndDataLen);
end else
begin // 没有结束符
FCacheBuffer.restoreReaderIndex;
Break;
OnDataAction(@FCacheBuffer.FRawBytes[0], FCacheBuffer.FRawLength);
ResetPacakge(@FCacheBuffer);
end;

end;
FCacheBuffer.clearHaveReadBuffer();




Expand Down Expand Up @@ -370,8 +358,7 @@ procedure TDiocpStringTcpServer.DoDataAction(pvContext: TDiocpExContext; pvData:
ansiStr:AnsiString;
begin
inherited;
SetLength(ansiStr, pvDataLen);
Move(pvData^, PAnsiChar(ansiStr)^, pvDataLen);
ansiStr := ByteBufferToString(PByte(pvData), pvDataLen);
if Assigned(FOnContextStringAction) then
begin
FOnContextStringAction(TDiocpStringContext(pvContext), ansiStr);
Expand Down

0 comments on commit ef4173a

Please sign in to comment.