Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Einige fragen zu TSocketServer und TSocketClient (https://www.delphipraxis.net/110133-einige-fragen-zu-tsocketserver-und-tsocketclient.html)

Thomas83 13. Mär 2008 12:59


Einige fragen zu TSocketServer und TSocketClient
 
hi zusammen,

habe versucht mit den Indys ein Netzwerkprotokoll aufzubauen.
Hatte einige Probleme mit den Threads.

Also versuche ich jetzt mein Protokoll mit den Sockets aufzubauen.
Habe mal das TermCharTutorial überflogen,
aber zuvor würde ich erst ein paar Fragen klären.

Wenn zwei Clients Daten, gleichzeitig, wie folgt senden würden
Client 1
SendBuffer(buffer1.1);
SendBuffer(buffer1.2);
Client 2
SendBuffer(buffer2.1);
SendBuffer(buffer2.1);

wie kommen diese beim Server an?
Kann ich erst den einen client abarbeiten und dann client zwei oder kommen die Daten einfach rein
buffer1.1 <- client 1
buffer2.1 <- client 2
buffer2.2 <- client 2
buffer1.2 <- client 1

Würde gerne die Daten ber Record versenden. Es gibt drei Records
Header, Daten, prüfsumme.

Als erstes sende ich den Header dann die daten und anschließend die prüfsumme.
In onexecute bzw. ClientRead würde ich es dann wie folgt machen
LeseHeader;
LeseDaten;
LesePrüfsumme;
Fürt das auch zu problemen?

Thomas83 13. Mär 2008 14:00

Re: Einige fragen zu TSocketServer und TSocketClient
 
habe es gerade mal getestet
wenn ich zwei client habe und per timer (0.1 sek) daten send
WriteBuffer(buffer1);
WriteBuffer(buffer2);
s := ReadString; //Antwort

im server kommen dann jedoch die paket unterschiedlich an
paket 1 von client 1
paket 1 von client 2
paket 2 von client 2
paket 1 von client 3
paket 2 von client 2

also müste ich in der ReadClient die Daten auslesen und anschliesend die datenpaket zuordnen.
bzw. die paket zusammen führen ,sehe ich das richtig?

Muetze1 13. Mär 2008 14:41

Re: Einige fragen zu TSocketServer und TSocketClient
 
Der Server hat doch mehrere Socketverbindungen zu jedem Client. Damit kann jeder Socket zur selben Zeit ihm was senden. Wenn beim Server nun ein Socket was empfangen hat von seinem Client, dann ruft der Server das OnClientRead Ereignis auf und übergibt genau den Socket als Argument, bei welchem was empfangen wurde. Du kannst somit über das Socket Argument die Clients eindeutig auseinander halten (die gleichen Instanzen findest du auch in der ServerSocket.Socket.Connections[] Eigenschaft wieder). Diese Instanzen sind über die gesamte Verbindungszeit eines Clients hin eindeutig und gleich.

Dann zu der Frage mit dem Packeten: wenn du vom Client z.B. folgenden String sendest:

Send("hallo");
Send("ballo");

dann kann der Server das z.B. so empfangen:

Receive("halloballo")

oder

Receive("hal");
Receive("l");
Receive("oball");
Receive("o");

jedes Receive("") steht für ein OnClientRead() Aufruf)

Mit anderen Worten: Die Sockets übertragen einfach nur die ihr angetragenen Bytes zu dem angetragenen Empfänger. Wie du den Sockets die Daten übergibst, also in gesonderten Aufrufen oder mit einem großen Aufruf interessiert den Socket nicht die Bohne. Wenn Bytes anstehen zum übertragen, dann überträgt er die. Er garantiert dir soweit nur, dass die Reihenfolge der Bytes eingehalten wird und auch entsprechend beim Empfänger ankommen.

Für alles andere ist ein Protokoll zuständig - die Sockets implementieren keins (wäre ja auch schlimm, dann wärst du auf ein Protokoll festgelegt und könntest dir schlecht ein eigenes implementieren), somit musst du dir eins ausdenken. Schon allein ein besonderes Zeichen als Trenner, welches in den Daten nicht vorkommt, wäre ein Protokoll. Damit kannst du erkennen, ob ein Packet vollständig ist bzw. wo es aufhört und das nächste anfängt, etc.

Thomas83 13. Mär 2008 14:52

Re: Einige fragen zu TSocketServer und TSocketClient
 
dank dir, das hilft einen schon mal ungemein weiter.....
hatte mir jetzt folgendes überlegt:
es gibt zwei records
Delphi-Quellcode:
rec1 = record
  int : integer;
end;
rec2 = record
  int : integer;
  str : string[100];
  cmd : integer;
end;
Wie kann ich diese jetzt beim Server und beim Client auseinander halten?
beim client schreibe ich einfach
SendBuffer(rec1,sizeof(rec1));
SendBuffer(rec2,sizeof(rec2));

doch beim Server weis ich ja nicht ob jetzt ein rec1 oder rec2 gesendet wird.
also denke ich mal das als erstes der typ ausgelesen werden muss.
Delphi-Quellcode:
ReadBuffer(typ,sizeof(integer));
case typ of
  0 : ReadBuffer(rec1,sizeof(rec1));
  1 : ReadBuffer(rec2,sizeof(rec2));
end;
wie könnte ich sowas in dieser Art implementieren?

Medium 13. Mär 2008 15:45

Re: Einige fragen zu TSocketServer und TSocketClient
 
Du müsstest dir den Typ schon selber mit senden. Wir machen es gewöhnlich so, dass wir jedem Record einen gleich aufgebauten Header verpassen, der den Typ der folgenden Daten z.B. in einem Zahlenwert oder kurzen String beschreibt, und ggf. die Länge. Dadurch kannst du, egal welcher Recordtyp kommt, erstmal davon ausgehen, dass die ersten paar Felder bei allen gleich sind, und die Daten darin beschreiben wie der Rest zu verstehen ist. Das ganze dann in eine Variable des ermittelten Typs moven, und fertig.

Thomas83 13. Mär 2008 15:55

Re: Einige fragen zu TSocketServer und TSocketClient
 
ach sorry habe ich vergessen, müste eigentlich dann ja so aussehen
Delphi-Quellcode:
rec1 = record
  typ : integer;
  int : integer;
end;
rec2 = record
  typ : integer;
  int : integer;
  str : string[100];
  cmd : integer;
end;
hättest du eventuell ein paar code schnipsel?
das wäre super.....

Jackie1983 13. Mär 2008 20:19

Re: Einige fragen zu TSocketServer und TSocketClient
 
hi,
bekomme immer eine zugriffsverletzung
Delphi-Quellcode:
type
  TBytes = array of byte;

...
var
  data : TBytes;
  len : integer;
begin
  len := Socket.ReceiveLength;
  SetLength(data,len);
  Socket.ReceiveBuf(data,len);
  ...
end;
es sind keine daten in data.....
mache ich was falsch?
wenn ich es mit TByteArray mache funktioniert es ohne probleme.
Der Typ hat aber eine feste größe.

Muetze1 14. Mär 2008 00:45

Re: Einige fragen zu TSocketServer und TSocketClient
 
Zitat:

Zitat von Thomas83
Wie kann ich diese jetzt beim Server und beim Client auseinander halten?

Genau dafür ist das o.g. Protokoll da. Du musst die Daten logisch verwalten können und das macht ein Protokoll, es bringt eine logische Ordnung in die Daten.

Und zu deinem Problem:

Delphi-Quellcode:
type
  TBytes = array of byte;

...
var
  data : TBytes;
  len : integer;
begin
  len := Socket.ReceiveLength;
  SetLength(data,len);
  Socket.ReceiveBuf(data[0],len);
  ...
end;
Das erste Element angeben, ansonsten schreibt er die Daten dahin, wo das Array hinterlegt ist, aber nicht die Array Elemente an sich.

Thomas83 14. Mär 2008 06:15

Re: Einige fragen zu TSocketServer und TSocketClient
 
danke habe es hinbekommen.
Habe es so gemacht wie du oben geschrieben hast,
das erste byte ist immer der typ, somit kann ich daran erkennen was für daten anschliesend im buffer sind.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:00 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