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:
| Client := TClientSocket.create( Nil ); Client.ClientType := ctNonBlocking; while not Terminated do begin zS := ToSend.Gib; if (zS<>Nil) then 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!
IhopeonlyReader hat folgendes geschrieben : |
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
Narses hat folgendes geschrieben : |
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
knittel hat folgendes geschrieben : |
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.
knittel hat folgendes geschrieben : |
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
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!