AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Socket C&S

Ein Thema von tomkupitz · begonnen am 6. Feb 2018 · letzter Beitrag vom 9. Feb 2018
 
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#7

AW: Socket C&S

  Alt 6. Feb 2018, 23:00
Dieses Beispiel solltest du 1 zu 1 auf Sockets übertragen können:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    ...
  strict private
    FBuffer: TMemoryStream;
    FBufferLen: UInt32;

...

procedure TForm1.Recv(const Data: TBytes);
type
  PUInt32 = ^UInt32;
var
  N: UInt32;
  S: String;
begin
  // Erstmal alle Daten in den Buffer schreiben
  FBuffer.Write(Data, Length(Data));
  Inc(FBufferLen, Length(Data));

  // Pakete parsen
  while (FBufferLen >= SizeOf(N)) do
  begin
    N := PUInt32(FBuffer.Memory)^;
    if (FBufferLen < SizeOf(N) + N) then
    begin
      Break;
    end;
    // Mindestens ein Paket vollständig angekommen
    SetLength(S, N div SizeOf(Char));
    CopyMemory(@S[1], PByte(FBuffer.Memory) + SizeOf(N), N);
    ShowMessage(S);

    // Jetzt muss das bearbeitete Paket aus dem Buffer "entfernt" werden
    CopyMemory(FBuffer.Memory, PByte(FBuffer.Memory) + SizeOf(N) + N,
      FBufferLen - SizeOf(N) - N);
    Dec(FBufferLen, SizeOf(N) + N);
    FBuffer.Position := FBuffer.Position - SizeOf(N) - N;
  end;
end;
Hier noch zwei Testvektoren:
Delphi-Quellcode:
procedure TForm1.TestFragmented;
const
  S = 'Dieser String wird mehreren Paketen gesendet';
  X = 40;
var
  N: UInt32;
  D, F1, F2: TBytes;
begin
  N := Length(S) * SizeOf(Char);
  SetLength(D, SizeOf(N) + N);
  Move(N, D[0], SizeOf(N));
  Move(S[1], D[SizeOf(N)], N);
  SetLength(F1, X);
  Move(D[0], F1[0], X);
  SetLength(F2, Length(D) - X);
  Move(D[X], F2[0], Length(D) - X);
  // Einzelnes Paket wird fragmentiert empfangen
  Recv(F1);
  Recv(F2);
end;

procedure TForm1.TestMultiple;
const
  S1 = 'Dies ist String 1';
  S2 = 'Dies ist String 2';
var
  N1, N2: UInt32;
  D: TBytes;
begin
  N1 := Length(S1) * SizeOf(Char);
  N2 := Length(S2) * SizeOf(Char);
  SetLength(D, SizeOf(N1) + N1 + SizeOf(N2) + N2);
  Move(N1, D[0], SizeOf(N1));
  Move(S1[1], D[SizeOf(N1)], N1);
  Move(N2, D[SizeOf(N1) + N1], SizeOf(N2));
  Move(S2[1], D[SizeOf(N1) + N1 + SizeOf(N2)], N2);
  // Zwei Pakete werden als einzelnes Paket empfangen
  Recv(D);
end
Ich verwende hier absichtlich das extra Feld FBufferLen statt direkt FBuffer.Size , um frequente Speicher-Allocs zu vermeiden.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz