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
Antwort Antwort
Seite 3 von 3     123   
Benutzerbild von Zacherl
Zacherl

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

AW: Socket C&S

  Alt 9. Feb 2018, 20:24
Also tatsächlich nonblocking Sockets?

Eine Sache, die mir grade noch auffällt, ist das Speichern/Laden des Bitmaps. Gibt es einen Grund, warum du nicht z.b. TMemoryStream verwendest? Dann reduziert sich dein kompletter Code mit den ScanLine s nämlich auf ein
Delphi-Quellcode:
I := 1234;
Stream.Write(I);
Bitmap.SaveToStream(Stream)
analog dazu das Laden:
Delphi-Quellcode:
Stream.Read(I);
if (I = 1234) then
  Bitmap.LoadFromStream(Stream)
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von scrat1979
scrat1979

Registriert seit: 12. Jan 2007
Ort: Sulzbach a.d. Murr
1.028 Beiträge
 
Delphi 10.4 Sydney
 
#22

AW: Socket C&S

  Alt 9. Feb 2018, 20:37
Ich kann dir die sgcWebSockets nur wärmstens empfehlen. Damit habe ich mir innerhalb von paar Stunden meinen eigenen Server und Client abgeleitet und jetzt wird er für einen netzwerkfähigen Terminkalender verwendet. Einfach klasse!
Michael Kübler
  Mit Zitat antworten Zitat
tomkupitz

Registriert seit: 26. Jan 2011
323 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Socket C&S

  Alt 9. Feb 2018, 21:07
Zitat:
Also tatsächlich nonblocking Sockets?
ja, nonblocking.

Zitat:
Gibt es einen Grund, warum du nicht z.b. TMemoryStream verwendest?
nein, habe ich nur zu Testzwecken verwendet, ist also noch nicht "optimiert".
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

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

AW: Socket C&S

  Alt 9. Feb 2018, 23:31
So in etwa würde ich vorgehen, um direkt nach dem Connecten einen simplen String an den Server zu schicken (btw. die Socket Komponenten sind schon sehr lange deprecated und evtl. könnten blocking Sockets hier für dich auch besser geeignet sein):
Delphi-Quellcode:
unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Win.ScktComp;

type
  TSocketBufferDataEvent =
    procedure (Sender: TOBject; Socket: TCustomWinSocket; const Data: TBytes) of Object;

  TSocketBuffer = class(TObject)
  strict private
    FBuffer: TMemoryStream;
    FLength: UInt32;
  strict private
    FOnData: TSocketBufferDataEvent;
  public
    procedure Receive(Socket: TCustomWinSocket);
  public
    constructor Create;
    destructor Destroy; override;
  public
    property OnData: TSocketBufferDataEvent read FOnData write FOnData;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  strict private
    FClient: TClientSocket;
    FClientBuffer: TSocketBuffer;
    FServer: TServerSocket;
  strict private
    procedure Send(Socket: TCustomWinSocket; const Data: TBytes);
  strict private
    procedure ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientData(Sender: TOBject; Socket: TCustomWinSocket; const Data: TBytes);
    procedure ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ServerData(Sender: TOBject; Socket: TCustomWinSocket; const Data: TBytes);
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

uses
  System.Math;

{$R *.dfm}

{ TSocketBuffer }

constructor TSocketBuffer.Create;
begin
  inherited Create;
  FBuffer := TMemoryStream.Create;
  FLength := 0;
end;

destructor TSocketBuffer.Destroy;
begin
  FBuffer.Free;
  inherited;
end;

procedure TSocketBuffer.Receive(Socket: TCustomWinSocket);
type
  PUInt32 = ^UInt32;
var
  B: array[0..64*1024 - 1] of Byte;
  N: UInt32;
  D: TBytes;
begin
  // Erstmal alle Daten in den Buffer schreiben
  while (Socket.ReceiveLength > 0) do
  begin
    N := System.Math.Min(Socket.ReceiveLength, Length(B));
    Socket.ReceiveBuf(B[0], N);
    FBuffer.Write(B[0], N);
    Inc(FLength, N);
  end;

  // Pakete parsen
  while (FLength >= SizeOf(N)) do
  begin
    N := PUInt32(FBuffer.Memory)^;
    if (FLength < SizeOf(N) + N) then
    begin
      Break;
    end;
    // Mindestens ein Paket vollständig angekommen
    SetLength(D, N);
    CopyMemory(@D[0], PByte(FBuffer.Memory) + SizeOf(N), N);
    if Assigned(FOnData) then
    begin
      FOnData(Self, Socket, D);
    end;

    // Jetzt muss das bearbeitete Paket aus dem Buffer "entfernt" werden
    CopyMemory(FBuffer.Memory, PByte(FBuffer.Memory) + SizeOf(N) + N, FLength - SizeOf(N) - N);
    Dec(FLength, SizeOf(N) + N);
    FBuffer.Position := FBuffer.Position - SizeOf(N) - N;
  end;
end;

{ TForm2 }

procedure TForm2.Button1Click(Sender: TObject);
begin
  FClient.Active := true;
end;

procedure TForm2.ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Send(Socket, TEncoding.UTF8.GetBytes('This is a test string'));
end;

procedure TForm2.ClientData(Sender: TOBject; Socket: TCustomWinSocket; const Data: TBytes);
begin
  // Vollständiges Paket vom Server empfangen

end;

procedure TForm2.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
begin
  FClientBuffer.Receive(Socket);
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  FClient := TClientSocket.Create(Self);
  FClient.ClientType := ctNonBlocking;
  FClient.Host := 'localhost';
  FClient.Port := 12345;
  FClient.OnConnect := ClientConnect;
  FClient.OnRead := ClientRead;
  FClientBuffer := TSocketBuffer.Create;
  FClientBuffer.OnData := ClientData;
  FServer := TServerSocket.Create(Self);
  FServer.ServerType := stNonBlocking;
  FServer.Port := 12345;
  FServer.OnClientConnect := ServerClientConnect;
  FServer.OnClientDisconnect := ServerClientDisconnect;
  FServer.OnClientRead := ServerRead;
  FServer.Active := true;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  FClientBuffer.Free;
end;

procedure TForm2.Send(Socket: TCustomWinSocket; const Data: TBytes);
var
  N, S: UInt32;
begin
  N := Length(Data);
  S := 0;
  Assert(Socket.SendBuf(N, SizeOf(N)) = 4);
  while (S < N) do
  begin
    Inc(S, Socket.SendBuf(Data[S], N - S));
  end;
end;

procedure TForm2.ServerClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var
  Buffer: TSocketBuffer;
begin
  Buffer := TSocketBuffer.Create;
  Buffer.OnData := ServerData;
  Socket.Data := Buffer;
end;

procedure TForm2.ServerClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  TSocketBuffer(Socket.Data).Free;
end;

procedure TForm2.ServerData(Sender: TOBject; Socket: TCustomWinSocket; const Data: TBytes);
begin
  // Vollständiges Paket vom Client empfangen
  Caption := TEncoding.UTF8.GetString(Data);
end;

procedure TForm2.ServerRead(Sender: TObject; Socket: TCustomWinSocket);
begin
  TSocketBuffer(Socket.Data).Receive(Socket);
end;

end.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz