AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

NamedPipe @Buffer[0] exception

Ein Thema von Corelgott · begonnen am 17. Aug 2009 · letzter Beitrag vom 17. Aug 2009
 
Benutzerbild von Corelgott
Corelgott

Registriert seit: 11. Apr 2003
Ort: Lübeck
213 Beiträge
 
Delphi 2006 Enterprise
 
#1

NamedPipe @Buffer[0] exception

  Alt 17. Aug 2009, 10:09
Hi @ all,

ich quäle mich schon seit Tagen mit der Kommunikation per Named Pipes. An sich ist das ja nicht weiter schwer aber:
Ich habe das Problem, dass ich grundsätzlich beim 2. Versuch von Client zum Host etwas zu übermitteln eine Exception bekomme...

Mein Host sieht so aus:

Delphi-Quellcode:
function TPipeHost.createConnection(pipeName: string): HWND;
var
  FSA : SECURITY_ATTRIBUTES;
  FSD : SECURITY_DESCRIPTOR;
  verbs : Cardinal;
  Mode : Cardinal;

begin
  self.FPipeName := pipeName;

  verbs := PIPE_TYPE_BYTE or PIPE_WAIT or PIPE_READMODE_BYTE;

  InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(@FSD, True, nil, False);
  FSA.lpSecurityDescriptor := @FSD;
  FSA.nLength := sizeof(SECURITY_ATTRIBUTES);
  FSA.bInheritHandle := True;
  result := CreateNamedPipe(PChar('\\.\pipe\' + pipeName), PIPE_ACCESS_DUPLEX, verbs,
                            PIPE_UNLIMITED_INSTANCES, buffersize,
                            buffersize, NMPWAIT_USE_DEFAULT_WAIT, nil);
  if isConsole then
    writeln(Format('Created Pipe with handle: %d', [result]))

end;
Der Client macht dann folgendes:

Delphi-Quellcode:
function TPipeClient.createConnection(pipeName: string): HWND;
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;

   self.FPipeName := pipeName;

   result := CreateFile(PChar('\\.\pipe\' + pipeName),
                     GENERIC_READ or GENERIC_WRITE,
                     PIPE_TYPE_BYTE,
                     @FSA,
                     OPEN_EXISTING,
                     0,
                     0);
  if isConsole then
    writeln(Format('Connected to Pipe with handle: %d', [result]))
end;
Der Host läuft in seinem eigenen thread und überprüft ob Daten vorhanden sind via:

Delphi-Quellcode:
function TCustomPipe.dataAvailable: Cardinal;
var
  readCount : LongWord;
  rest : LongWord;

begin
  result := 0;
  rest := 0;
  readCount := 0;

  // get data from pipe
  if self.hasValidHandle() then
    PeekNamedPipe(self.getHandle(), @self.FBuffer[0], BufferSize, @readCount, @rest, nil);

  result := rest;
end;
Nun kommt das problem: das auslesen:
Delphi-Quellcode:

type TPipeHost
  strict private
    FBuffer : TByteDynArray;

// [.... snip .... ]


procedure TCustomPipe.cleanBuffer();
begin
  // resize & init
  setLength(FBuffer, buffersize);
  FillChar(self.FBuffer[0], length(self.FBuffer), #0);
end;

// method to read data
procedure TCustomPipe.readData(var data : TByteList);
var
  dataCount : Cardinal;
  dataRead : Cardinal;
  callBack : Pointer;

begin
  dataRead := 0;
  dataCount := self.dataAvailable();

  // hwnd <> 0 && hwnd <> INVALID_HANDLE
  if self.hasValidHandle then
  begin
    EnterCriticalSection(self.FSection);

    // got data?
    while(dataCount > 0) do
    begin
      try

        self.cleanBuffer();

        (* Hier kommt das Problem: ReadFile verändert mir die Größe meines Dyn-Array (!?!) und ne Access-Voilation-Exception (Was ein wunder, wenn die API das Array kaputt macht...)
          Sowie ich self.FBuffer[0] übergebe bekomme ich 1. Nur noch mist an Daten & 2. Ne tolle Exception
        *)

        ReadFile(self.getHandle(), self.FBuffer, dataCount, dataRead, nil);

        // process data

        // look if there is any new data left
        dataCount := self.dataAvailable();
      finally
        // dispose buffer
        setLength(buffer, 0);
      end;
    end;
    LeaveCriticalSection(self.FSection);
  end;
end;
Was Mache ich falsch? Darf ich kein Array of Byte übergeben? Was ich bei dem Thread nicht tue ist nach jedem Lesen die datei wieder zu schließen... Wie das in so vielen Beispielen gemacht wird...

Hat wer nen Tipp für mich? Oder vielleicht ein Beispiel? Ich hatte leider bei Lunkie nix gefunden und auch meine Google Exkursionen waren nicht gerade erfolgreich. Die Forum-Suche brachte auch nichts zu tage, was meinen effekt auch nur ansatzweise erklären könnte?

Schon mal vielen Dank für's Nachdenken im Voraus!

Gruß

Corelgott
wer Rächtschraibfehler findet daaf sie behalten...
  Mit Zitat antworten Zitat
 

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:40 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