program Server;
uses
System.Classes,
System.SysUtils,
System.SyncObjs,
IdTCPServer,
IdContext,
IdGlobal,
System.Generics.Collections,
System.Diagnostics;
type
TDataQueue =
class
private
FQueue: TQueue<TIdBytes>;
FLock: TCriticalSection;
public
constructor Create;
destructor Destroy;
override;
procedure Enqueue(
const Data: TIdBytes);
function Dequeue: TIdBytes;
end;
TProcessingThread =
class(TThread)
private
FDataQueue: TDataQueue;
Anz : Integer;
protected
procedure Execute;
override;
public
constructor Create(ADataQueue: TDataQueue);
end;
TMyTCPServer =
class
private
FServer: TIdTCPServer;
FDataQueue: TDataQueue;
FProcessingThread: TProcessingThread;
procedure OnExecuteHandler(AContext: TIdContext);
public
constructor Create;
destructor Destroy;
override;
procedure Start;
procedure Stop;
end;
{ TDataQueue }
constructor TDataQueue.Create;
begin
FQueue := TQueue<TIdBytes>.Create;
FLock := TCriticalSection.Create;
end;
destructor TDataQueue.Destroy;
begin
FQueue.Free;
FLock.Free;
inherited;
end;
procedure TDataQueue.Enqueue(
const Data: TIdBytes);
begin
FLock.Acquire;
try
FQueue.Enqueue(Data);
finally
FLock.Release;
end;
end;
function TDataQueue.Dequeue: TIdBytes;
begin
FLock.Acquire;
try
if FQueue.Count > 0
then
Result := FQueue.Dequeue
else
SetLength(Result, 0);
finally
FLock.Release;
end;
end;
{ TProcessingThread }
constructor TProcessingThread.Create(ADataQueue: TDataQueue);
begin
FDataQueue := ADataQueue;
Anz := 0;
inherited Create(False);
end;
procedure TProcessingThread.Execute;
var
Data: TIdBytes;
sw3 : TStopwatch;
t3 : Int64;
begin
while not Terminated
do
begin
Data := FDataQueue.Dequeue;
if Length(Data) > 0
then
begin
Inc(Anz, Length(Data));
Writeln('
Empfangen: ', Length(Data), '
Bytes' + '
- Anz: ' + Anz.ToString);
Writeln('
Gesamtlänge: ' + Anz.ToString + '
Bytes');
end
else
Sleep(1);
end;
end;
{ TMyTCPServer }
constructor TMyTCPServer.Create;
begin
FDataQueue := TDataQueue.Create;
FProcessingThread := TProcessingThread.Create(FDataQueue);
FServer := TIdTCPServer.Create(
nil);
FServer.DefaultPort := 5000;
FServer.OnExecute := OnExecuteHandler;
end;
destructor TMyTCPServer.Destroy;
begin
Stop;
FreeAndNil(FServer);
FreeAndNil(FProcessingThread);
FreeAndNil(FDataQueue);
inherited;
end;
procedure TMyTCPServer.OnExecuteHandler(AContext: TIdContext);
var
Buffer: TIdBytes;
begin
//SetLength(Buffer, 61000); //<- nicht feste größe einlesen
while AContext.Connection.IOHandler.InputBuffer.Size > 0
do
begin
SetLength(Buffer, AContext.Connection.IOHandler.InputBuffer.Size);
//<- so viel einlesen wie im Buffer enthalten ist
AContext.Connection.IOHandler.ReadBytes(Buffer, Length(Buffer), False);
FDataQueue.Enqueue(Buffer);
end;
end;
procedure TMyTCPServer.Start;
begin
FServer.Active := True;
end;
procedure TMyTCPServer.Stop;
begin
FServer.Active := False;
end;
var
MyServer: TMyTCPServer;
begin
try
MyServer := TMyTCPServer.Create;
MyServer.Start;
Writeln('
Server läuft auf Port 5000. Drücke Enter zum Beenden.');
Readln;
MyServer.Stop;
FreeAndNil(MyServer);
except
on E:
Exception do
Writeln('
Fehler: ', E.
Message);
end;
end.