Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Senden an Named Pipe klappt nur zum Server! Warum?[erledigt] (https://www.delphipraxis.net/147369-senden-named-pipe-klappt-nur-zum-server-warum-%5Berledigt%5D.html)

DualCoreCpu 6. Feb 2010 23:46


Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Hallo,

das das Thema ähnlich ist zu diesem hier, wo ich auch die Quelltexte hinterlegt habe:

http://www.delphipraxis.net/internal...127785#1127785

verlinke ich das mal hier.

Da die Regeln hier vorsehen: Für jede Frage ein neuer Thread, will ich mich an diese Konvention halten und einen neuen Thread eröffnen.

Habe mein Problem mit der Datenübertragung per Named Pipe so weit gelöst, das ich meine Daten vom Client zum Server übertragen kann, jedoch nicht umgekehrt. Die Antwort vom Server kann mein Client nicht empfangen, obwohl ich das Flag PIPE_ACCESS_DUPLEX gesetzt habe.

Was muss ich noch verändern, damit die Übertragung in beiden Richtungen funktioniert?

Der aktuelle Quelltext ist unter dem oben genannten Link zu finden.

schöni 7. Feb 2010 16:27

Re: Senden an Named Pipe klappt nur zum Server! Warum?
 
Hallo DualCoreCpu,

So hier sollte es in beiden Richtungen klappen. Hab ich grad getestet, weil ich das für meine Zwecke auch brauche. Hab ich dann beim Stöbern gefunden.

Programm A:

SERVERSEITE

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
   FSA : SECURITY_ATTRIBUTES;
   FSD : SECURITY_DESCRIPTOR;
   pch1: shortstring;
begin
   InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
   SetSecurityDescriptorDacl(@FSD, True, nil, False);
   FSA.lpSecurityDescriptor := @FSD;
   FSA.nLength := sizeof(SECURITY_ATTRIBUTES);
   FSA.bInheritHandle := True;

   Pipe:= CreateNamedPipe(PChar('\\.\pipe\<test>'),
                          PIPE_ACCESS_DUPLEX or FILE_FLAG_WRITE_THROUGH,
                          PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_NOWAIT,
                          PIPE_UNLIMITED_INSTANCES,
                          1024,
                          1024,
                          50,
                          @FSA);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   buffer: shortstring;
   dw   : dword;
   b1    : boolean;
begin
   buffer:= 'Test';
   WriteFile(Pipe, buffer, sizeof(buffer), dw, nil);
end;
Programm B:

CLIENTSEITE

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
   FSA : SECURITY_ATTRIBUTES;
   FSD : SECURITY_DESCRIPTOR;
begin
   InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
   SetSecurityDescriptorDacl(@FSD, True, nil, False);
   FSA.lpSecurityDescriptor := @FSD;
   FSA.nLength := sizeof(SECURITY_ATTRIBUTES);
   FSA.bInheritHandle := True;

   Pipe:= CreateFile(PChar('\\.\pipe\<test>'),
                     GENERIC_READ or GENERIC_WRITE,
                     0,
                     @FSA,
                     OPEN_EXISTING,
                     0,
                     0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   buffer: shortstring;
   dw   : dword;
begin
   ReadFile(Pipe, buffer, sizeof(buffer), dw, nil);
end;

DualCoreCpu 7. Feb 2010 17:53

Re: Senden an Named Pipe klappt nur zum Server! Warum?
 
Danke, wie verrückt! Jetzt funktioniert es in beiden Richtungen! :hello:

Jetzt kann ich daraus ein steuerbares Pipe-Client/Server Paar bauen. :coder2:

Das will ich ohne fremde Hilfe schaffen!

Will ja selber auch was lernen dabei!

v2afrank 2. Mär 2011 08:43

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Ich hole den Thread mal wieder nach oben. Ich wollte das gerade mal in Delphi 2010 nachvollziehen. Da funktioniert es nicht. Die Clientseite empfängt nichts. Muss man unter Delphi 2010 noch was beachten ?

Bummi 2. Mär 2011 10:40

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
folgender Code funtioniert
Delphi-Quellcode:
procedure InitializeSecurity(var SA: TSecurityAttributes;ACL:PACL=nil);
var sd:        PSecurityDescriptor;
begin

  // Allocate memory for the security descriptor
  sd:=AllocMem(SECURITY_DESCRIPTOR_MIN_LENGTH);

  // Initialise the new security descriptor
  InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);

  // Add a NULL descriptor ACL to the security descriptor
  SetSecurityDescriptorDacl(sd, True, ACL, False);

  // Set up the security attributes structure
  with SA do
  begin
     nLength:=SizeOf(TSecurityAttributes) ;
     lpSecurityDescriptor:=sd;
     bInheritHandle:=True;
  end;

end;
ist eine aufgebohrte Version der freien Komponenten hinter diesem Link
http://cc.embarcadero.com/Item/21507

v2afrank 2. Mär 2011 11:01

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Es tut mir Leid. Damit bekomme ich es aber auch nicht aml Laufen. Die Komponenten verbinden sich noch nicht einmal untereinander. Hast DU da ein kleines Demoprogramm ?
Wie gesagt. Unter Delphi 2010

Bummi 2. Mär 2011 11:48

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Liste der Anhänge anzeigen (Anzahl: 1)
Auf Basis der Komponenten?
liegt bei, die Eigenschaft ACLFilename fehlt in den Originalkomponenten, einfach ignorieren drücken..

v2afrank 10. Mär 2011 06:22

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Es tut mir Leid dass ich mich erst jetzt melden konnte.
Es funktioniert wie erhofft. Danke

v2afrank 18. Mär 2011 07:49

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Ich habe die Komponenten jetzt mal bei mir eingebaut und es funktioniert auch gut.

Allerdings habe ich jetzt einen Memoryleak.
Wenn ich Reportmemoryleaks on Shutdown auf true einstelle wird auch bei Deinem Beispielprogramm fogender Fehler angemerkt.
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:



21 - 28 bytes: TMemoryStream x 1

157 - 172 bytes: TPipeClientThread x 1



The sizes of unexpected leaked medium and large blocks are: 4140


---------------------------
OK
---------------------------

Der Fehler scheint wohl in der Komponente zu liegen. Hast Du da schon Erfahrungen gemacht ?

Bummi 18. Mär 2011 10:00

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Ja, danke für den Hinweis der Client scheint ein Memoryproblem zu haben, ich habe versucht den Fehler zu debuggen, habe aber bis jetzt noch keinen Erfolg gehabt ... wäre für sachdienliche Hinweise dankbar...

Bummi 18. Mär 2011 11:19

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Der Destructor des ClientThreads wird nie aufgerufen.
FreeOnTerminate ist true, OnTerminate wird aufgerufen. Hat jemand eine Idee?

Bummi 18. Mär 2011 11:46

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Schein eher ein Debuggerproblem zu sein...
Wenn man Pipeclient explizit frei gibt und kurz wartet vor das Programm geschlossen wird, werden keine Memoryleaks mehr attestiert.

himitsu 18. Mär 2011 12:20

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
Wann werden denn die Client-Threads beendet und wird da auch auf deren Beendigung gewartet?

Bummi 18. Mär 2011 12:47

AW: Senden an Named Pipe klappt nur zum Server! Warum?[erledigt]
 
ich nehme an es liegt daran dass im Destructor
Disconnect(false) statt DisConnect(true) aufgerufen wird... die entscheidenden Zeilen ....
Delphi-Quellcode:
destructor TPipeClient.Destroy;
begin

  // Disconnect if connected
  Disconnect(false);

  // Free resources
  FinalizeSecurity(FSA);
  CloseHandle(FKillEv);
  FWriteQueue.Free;
  DeAllocateHWnd(FHwnd);

  // Perform inherited
  inherited Destroy;

end;


procedure TPipeClient.Disconnect(const CanWait:Boolean);
begin
  if not Assigned(self) then
     Exit;
     
  // Exit if not connected
  if not(FConnected) then exit;

  // Signal the kill event
  SetEvent(FKillEv);

  // Terminate and wait for the worker thread to finish
  if Assigned(FWorker) then FWorker.Terminate;

  // *** Added by Russell on 01.19.2004 ***
  // Only wait if we are not in a destroying state
  if CanWait and not (csDestroying in ComponentState) then
     FWorker.WaitFor;

  // Set new state
  FConnected:=False;

end;


procedure TPipeClientThread.Execute;
var dwEvents:  Integer;
     bOK:       Boolean;
begin

  // Loop while not terminated
  while not(Terminated) do
  begin
     // Make sure we always have an outstanding read and write queued up
     bOK:=(QueuedRead and QueuedWrite);
     if bOK then
     begin
        // If we are in a pending write then we need will not wait for the
        // DataEvent, because we are already waiting for a write to finish
        dwEvents:=4;
        if FPendingWrite then Dec(dwEvents);
        // Handle the event that was signalled (or failure)
        case WaitForMultipleObjects(dwEvents, @FEvents, False, INFINITE) of
           // Killed by pipe server
           WAIT_OBJECT_0     : Terminate;
           // Read completed
           WAIT_OBJECT_0+1   : bOK:=CompleteRead;
           // Write completed
           WAIT_OBJECT_0+2   : bOK:=CompleteWrite;
           // Data waiting to be sent
           WAIT_OBJECT_0+3   : ; // Data available to write
        else
           // General failure
           FErrorCode:=GetLastError;
           bOK:=False;
        end;
     end;
     // Check status
     if not(bOK) then
     begin
        // Call OnError in the main thread if this is not a disconnect. Disconnects
        // have their own event, and are not to be considered an error
        if (FErrorCode <> ERROR_PIPE_NOT_CONNECTED) then PostMessage(FNotify, WM_PIPEERROR_W, FPipe, FErrorCode);
        // Terminate
        Terminate;
     end;
  end;

  // Make sure the handle is still valid
  if (FErrorCode <> ERROR_INVALID_HANDLE) then
  begin
     DisconnectNamedPipe(FPipe);
     CloseHandle(FPipe);
  end;

  // Close all open handles that we own
  CloseHandle(FOlapRead.hEvent);
  CloseHandle(FOlapWrite.hEvent);

end;


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