Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
{ **** UBPFD *********** by delphibase.endimus.com **** >> Приём и обработка пакетов переданных методом SendText() - с учётом "склеенных" и полученных неполностью пакетов. Юнит RecvPckt предназначен для приёма текста, передаваемого с помощью метода SendText объекта Socket:TCustomWinSocket. Данный юнит может использоваться как клиентом так и сервером для обработки принятого пакета. Функции данного юнита предусматривают возможность получения "склеенных" пакетов, или пакетов, пришедших не полностью. Тип TBuffer; FBuffer - хранит в себе принимаемый пакет FCurrentPacketSize = храни сведения о полной длине пакета. Описание функций и процедур, необходимых для использования в других юнитах Procedure ClearBuffer(var ABuffer:TBuffer); Очищает буффер FBuffer и обнуляет значение FCurrentPacketSize; Function ProcessReceivedPacket(var ABuffer:TBuffer; var APacket:String):Boolean; В данную функцию передаётся полученный от клиента/сервера пакет, через аргумент APacket Принцип работы этой функции заключается в накоплении получаемого текста в поле FBuffer объекта ABuffer. В случае когда FBuffer будет содержать полностью весь пакет, функция возвратит True, иначе возвращает False Функция ОТПРАВКИ текста: Function SendTextToSocket(Socket:TCustomWinSocket; Text:String):Integer; Var S:String; begin Result := -1; IF Text = '' then exit; IF Socket.Connected then begin S:=IntToStr(Length(Text)); Result := Socket.SendText(S+'#'+Text); end; end; Зависимости: sysutils Автор: VID, snap@iwt.ru, ICQ:132234868, Махачкала Copyright: VID Дата: 30 сентября 2002 г. ***************************************************** } unitRecvPckt; interface
uses
SysUtils; type
TReadHeaderResult = record
FPacketSize: Integer; FPacketSizeStr: string
; FTextStartsAt: Integer; end
; type
TBuffer = record
FBuffer: string
; FHeaderBuffer: string
; FCurrentPacketSize: Integer; end
; procedure
ClearBuffer(var
ABuffer: TBuffer); function
ReadHeader(var
ABuffer: TBuffer; var
APacket: string
): TReadHeaderResult; function
ProcessReceivedPacket(var
ABuffer: TBuffer; var
APacket: string
): Boolean; implementation
procedure
ClearBuffer(var
ABuffer: TBuffer); begin
ABuffer.FBuffer := ''; ABuffer.FHeaderBuffer := ''; ABuffer.FCurrentPacketSize := 0; end
; function
ReadHeader(var
ABuffer: TBuffer; var
APacket: string
): TReadHeaderResult; var
X, HBuffLen: Integer; procedure
ClearHeader; begin
ABuffer.FHeaderBuffer := ''; end
; function
CorrectPacket: Boolean; var
I, L: Integer; begin
X := 0; L := Length(APacket); for
I := 1 to
L do
if
(APacket[I] in
['0'..'9']) then
BREAK else
if
(APacket[I] = '#') and
(ABuffer.FHeaderBuffer <> '') then
BREAK else
X := I; if
X > 0 then
Delete(APacket, 1, X); RESULT := APacket <> ''; end
; procedure
GetHeader; var
I, L: Integer; begin
L := Length(APacket); X := 0; for
I := 1 to
L do
begin
X := I; if
(APacket[I] in
['0'..'9']) then
begin
HBuffLen := Length(ABuffer.FHeaderBuffer); if
HBuffLen > 0 then
Inc(HBuffLen); Insert(APacket[I], ABuffer.FHeaderBuffer, HBuffLen); end
else
Break; end
; end
; procedure
SetResultToNone; begin
Result.FPacketSize := 0; Result.FTextStartsAt := 0; Result.FPacketSizeStr := ''; end
; begin
SetResultToNone; if
APacket = '' then
Exit; if
ABuffer.FCurrentPacketSize > 0 then
begin
Result.FPacketSize := ABuffer.FCurrentPacketSize; Result.FPacketSizeStr := IntToStr(ABuffer.FCurrentPacketSize); Result.FTextStartsAt := 1; Exit; end
; if
not
CorrectPacket then
Exit; GetHeader; if
APacket[X] = '#' then
begin
Inc(X); try
Result.FPacketSize := StrToInt(ABuffer.FHeaderBuffer); except
end
; Result.FPacketSizeStr := ABuffer.FHeaderBuffer; ClearHeader; end
else
if
not
(APacket[X] in
['0'..'9']) then
ClearHeader; Result.FTextStartsAt := X; end
; function
ProcessReceivedPacket(var
ABuffer: TBuffer; var
APacket: string
): Boolean; var
ReadHeaderResult: TReadHeaderResult; NeedToCopy, DelSize: Integer; S: string
; BuffLen: Integer; function
FullPacket: Boolean; begin
Result := Length(ABuffer.FBuffer) = ABuffer.FCurrentPacketSize; end
; begin
Result := True; if
APacket = '' then
Exit; if
ABuffer.FBuffer = '' then
begin
ReadHeaderResult := ReadHeader(ABuffer, APacket); ABuffer.FCurrentPacketSize := ReadHeaderResult.FPacketSize; S := Copy(APacket, ReadHeaderResult.FTextStartsAt, ReadHeaderResult.FPacketSize); DelSize := Length(ReadHeaderResult.FPacketSizeStr) + ReadHeaderResult.FPacketSize + 1; end
else
begin
NeedToCopy := ABuffer.FCurrentPacketSize - Length(ABuffer.FBuffer); S := Copy(APacket, 1, NeedToCopy); DelSize := NeedToCopy; end
; if
ABuffer.FCurrentPacketSize > 0 then
begin
BuffLen := Length(ABuffer.FBuffer); if
BuffLen > 0 then
Inc(BuffLen); Insert(S, ABuffer.FBuffer, BuffLen); end
; if
not
FullPacket then
Result := False; if
ABuffer.FHeaderBuffer = '' then
DELETE(APacket, 1, DelSize) else
begin
APacket := ''; Result := False; end
; end
; end
.
Пример использования:
// Объявляем переменную типа TBuffer. Для каждого клиента на // сервере должна быть объявлена отдельная переменная этого типа varGBuffer: TBuffer; ... procedure
TForm1.ServerClientRead(Sender: TObject; Socket: TCustomWinSocket); var
S: string
; begin
S := Socket.ReceiveText; repeat
if
ProcessReceivedPacket(GBuffer, S) then
begin
if
GBuffer.FBuffer <> '' then
Recv.Lines.Add(GBuffer.FBuffer); //или же передать GBuffer.FBuffer на исполнение. ClearBuffer(GBuffer); end
; until
S = ''; end
;