Einzelnen Beitrag anzeigen

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, 11: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