Entwickler-Ecke

Internet / Netzwerk - [Delphi] Client- Multithreading


IhopeonlyReader - Fr 23.08.13 15:21
Titel: [Delphi] Client- Multithreading
Guten Tag,
der TServerSocket kann ja "mehrere" Streams gleichzeitig empfangen. Wenn er sendet, hängt er sich aber auf oder?

So dasselbe beim Client: Ich habe einen Thread in dem ich empfangen möchte, hier habe ich bereits das Problem, dass ich ohne die entsprechenden "On-Read" .. proceduren klar kommen muss, wie kann ich das selber schreiben? (muss ich da ne dauerschleife machen?)
Wenn ich jetzt senden würde, könnte ich auf ctblocking und ctnonblocking stellen.. ich habe 2 queques (ToSend und Rev) sollte ich 2 Threads machen um diese zufüllen/abzuarbeiten? oder reicht 1er?

ich möchte eigentlich nur ein/zwei thread haben, in dem alles von der ToSendQueue alles gesendet wird und alles "empfangene" auf den Rev stapel abgelegt wird. Das natürlich möglichst ohne Verzögerung!

Reicht es so?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
//Execute
//var zS: TStream;
//iLen: Integer; Bfr: Pointer;
Client := TClientSocket.create( Nil );
Client.ClientType := ctNonBlocking;
//Client connecten
while not Terminated do
 begin
 zS := ToSend.Gib;
 if (zS<>Nilthen
  Client.SendStream( zS );
 iLen := Socket.ReceiveLength; 
 if iLen>0 then
  begin
  GetMem(Bfr, iLen);
  try
  Client.Socket.ReceiveBuf(Bfr^, iLen);
  zS := TMemoryStream.create;
  zS.Write(Bfr^, iLen); 
  RevQueue.Drauf( zS ); 
    finally
    FreeMem(Bfr); 
    end;
  end
 end;
Client.Free;

oder wäre das in 2 Threads besser aufgehoben?

Was passiert wenn man es in 2 Threads macht und beide gleichzeitig auf den Client zugreifen? (Thread 1: Client.Socket.ReceiveBuf.. Thread 2: Client.SendStream)
könnte das fehler erzeugen oder kann der TClientSocket das?


IhopeonlyReader - Sa 24.08.13 18:15

- push -
Eigentliche Frage:
Zitat:
Was passiert wenn man es in 2 Threads macht und beide gleichzeitig auf den Client zugreifen?


Narses - So 25.08.13 11:25

Moin!

user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
Was passiert wenn man es in 2 Threads macht und beide gleichzeitig auf den Client zugreifen?
Da du den ClientSocket in dem Thread erstellst, geht das sowieso nicht mit 2 Threads. :nixweiss:

Abgesehen davon:

Delphi-Quelltext
1:
2:
Client := TClientSocket.create( Nil );
Client.ClientType := ctNonBlocking;
funktioniert das in einem Thread nicht, da geht nur ctBlocking. :idea:

cu
Narses


IhopeonlyReader - So 25.08.13 16:33

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Da du den ClientSocket in dem Thread erstellst, geht das sowieso nicht mit 2 Threads. :nixweiss:

Naja ich könnte Thread in Thread haben und den Client dann "übergeben" bzw. dessen Speicheradresse :wink:

Wenn ich ctBlocking verwenden MUSS, dann bringen mir 2 Threads auch nichts, da sie gegenseitig immer auf sich warten müssen, oder?
Beim empfangen sind ja zwischen den Paketen pausen, kann in der zeit etwas gesendet werden?

Wenn ja, dann würde ich 2 Threads verwenden, falls nicht, würde ich keinen Sinn sehen 2 zu verwenden


knittel - Mi 28.08.13 17:58

Also das Empfangen der Daten an sich kostet ja nicht so viel Zeit.

Das beste was du meiner Meinung nach machen könntest wäre die VCL OnRead ereignisse zu nutzen und beim hinzufügen zum buffer eine CriticalSection betreten. Diese verlässt du direkt danach wieder.

in deinem anderen Thread kannst du dann die Daten auslesen und immer wenn du die Daten lesen willst, musst du halt auch dort die CriticalSection betreten. Sobald du das Kommando (string) extrahiert hast kannst du die CriticalSection wieder verlassen und das Kommando bearbeiten.

Zum senden musst du dann dafür, genau wie du selbst gesagt hast eine ToSendQueue anlegen. Das Senden dann nachher nur noch z.B. am Ende der OnIdle Funktoin in deiner ToSendQueue abarbeiten. Das beste was du da noch machen kannst, ist vorher während des Multithreadings die Kommandos bereits als String aufbereitest.

Ich hoffe das hilft dir irgendwie weiter :)

EDIT:
Zitat:
Beim empfangen sind ja zwischen den Paketen pausen, kann in der zeit etwas gesendet werden?


Da sind Pausen? :?!?:


IhopeonlyReader - Mi 28.08.13 19:36

user profile iconknittel hat folgendes geschrieben Zum zitierten Posting springen:

Das beste was du meiner Meinung nach machen könntest wäre die VCL OnRead ereignisse zu nutzen und beim hinzufügen zum buffer eine CriticalSection betreten. Diese verlässt du direkt danach wieder

Aber wenn ich das in einem extra thread mache, wurde gesagt das ich ctblocking verweden muss, wie soll ich in einem Thread und mit ctblocking ein OnRead Ereignis bekommen? Einfach setzten geht nicht ! dann würde es nicht, falls es überhaupt klappen sollte, was ich nicht glaube, im Thread, sondern im "gui"-thread ausgeführt werden.. Wurde schonmal in einem anderen älteren Thread erwähnt.


user profile iconknittel hat folgendes geschrieben Zum zitierten Posting springen:

Da sind Pausen? :?!?:

Ja, Wenn man z.B. eine Datei per Stream vom Client zum Server schickt, kann man das gut beobachten, dass zwischen diesen "data packets" kleine pausen sind, oder Windows-Dateigrößenanzeige spinnt :D