AW: Socket C&S
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.
Delphi-Quellcode:
verwendest? Dann reduziert sich dein kompletter Code mit den
TMemoryStream
Delphi-Quellcode:
s nämlich auf ein
ScanLine
Delphi-Quellcode:
analog dazu das Laden:
I := 1234;
Stream.Write(I); Bitmap.SaveToStream(Stream)
Delphi-Quellcode:
Stream.Read(I);
if (I = 1234) then Bitmap.LoadFromStream(Stream) |
AW: Socket C&S
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!
|
AW: Socket C&S
Zitat:
Zitat:
|
AW: Socket C&S
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:53 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